";
/* selection variant if set */
$variant = MgFeatureSpatialOperations::Intersects;
if (isset($_REQUEST['variant'])) {
if (strcasecmp($_REQUEST['variant'],'contains') == 0) {
$variant = MgFeatureSpatialOperations::Contains;
} else if (strcasecmp($_REQUEST['variant'],'inside') == 0) {
$variant = MgFeatureSpatialOperations::Inside;
}
}
/* a filter expression to apply, in the form of an FDO SQL statement */
$filter = isset($_REQUEST['filter']) ? str_replace(array('*', '"'), array('%', "'"),html_entity_decode(urldecode( $_REQUEST['filter']))) : '';
//echo "\n";
/* a spatial filter in the form on a WKT geometry */
$spatialFilter = (isset($_REQUEST['spatialfilter']) && $_REQUEST['spatialfilter'] != '') ? urldecode($_REQUEST['spatialfilter']) : false;
//echo "spatial filter is $spatialFilter
";
/* we need a feature service to query the features */
$featureService = $siteConnection->CreateService(MgServiceType::FeatureService);
/* open the map from the session using the provided map name. The map was
previously created by calling LoadMap. */
$map = new MgMap();
$map->Open($resourceService, $mapName);
/* add the features to the map selection and save it*/
$selection = new MgSelection($map);
/* if extending the current selection */
$bExtendSelection = isset($_REQUEST['extendselection']) && strcasecmp($_REQUEST['extendselection'], 'true') == 0;
if ($bExtendSelection) {
$aLayerSelections = array();
$selection->Open($resourceService, $mapName);
$aLayers = selectionToArray($selection, array());
}
$bComputedProperties = isset($_REQUEST['computed']) && strcasecmp($_REQUEST['computed'], 'true') == 0;
$bQueryHiddenLayers = isset($_REQUEST['queryHiddenLayers']) && strcasecmp($_REQUEST['queryHiddenLayers'], 'true') == 0;
/*holds selection array*/
$properties = NULL;
$properties->layers = array();
/* Get the map SRS - we use this to convert distances */
$srsFactory = new MgCoordinateSystemFactory();
//safely get an SRS ... (in Utilities)
$srsDefMap = GetMapSRS($map);
$srsMap = $srsFactory->Create($srsDefMap);
$mapLayers = $map->GetLayers();
$bAllLayers = false;
$nLayers = count($layers);
if ($nLayers == 0) {
$nLayers = $mapLayers->GetCount();
$bAllLayers = true;
}
for ($i=0; $i<$nLayers; $i++) {
try {
if (!$bAllLayers) {
$layerObj = $mapLayers->GetItem($layers[$i]);
} else {
$layerObj = $mapLayers->GetItem($i);
}
$bVisFlag = $layerObj->IsVisible() || $bQueryHiddenLayers;
$className = $layerObj->GetFeatureClassName();
if (!$layerObj->GetSelectable() || !$bVisFlag ||
$className=='RedlineSchema:Redline' ||
!$className || $className=='rasters:RasterType' ||$className=='') {
continue;
}
/* get the feature source from the layer */
$featureResId = new MgResourceIdentifier($layerObj->GetFeatureSourceId());
$featureGeometryName = $layerObj->GetFeatureGeometryName();
$queryOptions = new MgFeatureQueryOptions();
/* the class that is used for this layer will be used to select
features */
$class = $layerObj->GetFeatureClassName();
//only retrieve properties that we actually need
$mappings = $_SESSION['property_mappings'][$layerObj->GetObjectId()];
//TODO : seems that property mapping breaks the selection ????
//could it be that $selection->AddFeatures($layerObj, $featureReader, 0) is
//the one causing a problem when the properies are limited ?
if (0 && count($mappings) > 0)
{
foreach($mappings as $name => $value) {
$queryOptions->AddFeatureProperty($name);
//echo "$name $value
\n";
}
$geomName = $layerObj->GetFeatureGeometryName();
$queryOptions->AddFeatureProperty($geomName);
}
//get the layer filter value if supplied
$layerReader = $resourceService->GetResourceContent($layerObj->GetLayerDefinition());
$xmldoc = DOMDocument::loadXML(ByteReaderToString($layerReader));
$xpathObj = new domXPath($xmldoc);
$xpathStr = "/LayerDefinition/VectorLayerDefinition/Filter"; //TODO: need this for DWF or Grid layers?
$xpathQuery = $xpathObj->query($xpathStr);
$layerFilter = '';
if ($xpathQuery->length > 0) {
$layerFilter = $xpathQuery->item(0)->nodeValue;
}
/* create the combined filter value*/
$combinedFilter = '';
if ($filter!='' && $layerFilter!='') {
$combinedFilter = "(".$filter.") AND (".$layerFilter.")";
} else {
$combinedFilter = $filter.$layerFilter;
}
if ($combinedFilter!='') {
//echo "/* setting combinedFilter:".$combinedFilter."*/";
$queryOptions->SetFilter($combinedFilter);
}
if ($spatialFilter !== false ) {
$spatialContext = $featureService->GetSpatialContexts($featureResId, true);
$srsLayerWkt = false;
if ($spatialContext != null && $spatialContext->ReadNext() != null) {
$srsLayerWkt = $spatialContext->GetCoordinateSystemWkt();
/* skip this layer if the srs is empty */
}
if ($srsLayerWkt == null) {
$srsLayerWkt = $srsDefMap;
}
/* create a coordinate system from the layer's SRS wkt */
$srsLayer = $srsFactory->Create($srsLayerWkt);
$verMajor = subStr(GetSiteVersion(), 0,1);
if ($verMajor == '1') {
$srsXform = new MgCoordinateSystemTransform($srsMap, $srsLayer);
} else {
$srsXform = $srsFactory->GetTransform($srsMap, $srsLayer);
}
$wktRW = new MgWktReaderWriter();
$geom = $wktRW->Read($spatialFilter, $srsXform);
$queryOptions->SetSpatialFilter($featureGeometryName, $geom, $variant);
}
/* select the features */
try {
$featureReader = $featureService->SelectFeatures($featureResId, $class, $queryOptions);
} catch (MgException $e) {
echo "ERROR2: " . $e->GetMessage() . "\n";
echo $e->GetDetails() . "\n";
echo $e->GetStackTrace() . "\n";
}
//debug block
//$testSelection = new MgSelection($map);
//$testSelection->AddFeatures($layerObj, $featureReader, $maxFeatures);
//$featureReader->Close();
//echo "/* features selected:".$testSelection->ToXML()."*/";
//$featureReader = $featureService->SelectFeatures($featureResId, $class, $queryOptions);
$layerName = $layerObj->GetName();
array_push($properties->layers, $layerName);
if ($bExtendSelection) {
/* possibly toggle features in the map */
$newSelection = new MgSelection($map);
$newSelection->AddFeatures($layerObj, $featureReader, $maxFeatures);
$aLayers = selectionToArray($newSelection, $aLayers);
} else {
try {
$spatialContext = $featureService->GetSpatialContexts($featureResId, true);
$srsLayerWkt = false;
if($spatialContext != null && $spatialContext->ReadNext() != null) {
$srsLayerWkt = $spatialContext->GetCoordinateSystemWkt();
/* skip this layer if the srs is empty */
}
if ($srsLayerWkt == null) {
$srsLayerWkt = $srsDefMap;
}
/* create a coordinate system from the layer's SRS wkt */
$srsLayer = $srsFactory->Create($srsLayerWkt);
// exclude layer if:
// the map is non-arbitrary and the layer is arbitrary or vice-versa
// or
// layer and map are both arbitrary but have different units
//
$bLayerSrsIsArbitrary = ($srsLayer->GetType() == MgCoordinateSystemType::Arbitrary);
$bMapSrsIsArbitrary = ($srsMap->GetType() == MgCoordinateSystemType::Arbitrary);
$bNeedsTransform = false;
if (($bLayerSrsIsArbitrary != $bMapSrsIsArbitrary) ||
($bLayerSrsIsArbitrary && ($srsLayer->GetUnits() != $srsMap->GetUnits()))) {
$bComputedProperties = false;
} else {
$srsTarget = null;
$srsXform = null;
$bNeedsTransform = ($srsLayer->GetUnitScale() != 1.0);
}
} catch (MgException $e) {
echo "ERROR: " . $e->GetMessage() . "\n";
echo $e->GetDetails() . "\n";
echo $e->GetStackTrace() . "\n";
}
/* add the features to the map */
$selection->AddFeatures($layerObj, $featureReader, $maxFeatures);
$featureReader = $featureService->SelectFeatures($featureResId, $class, $queryOptions);
$properties = BuildSelectionArray($featureReader, $layerName, $properties,
$bComputedProperties,
$srsLayer, $bNeedsTransform, $layerObj);
}
/* close the feature reader - not doing this could cause problems */
$featureReader->Close();
} catch (MgObjectNotFoundException $onfe) {
//skip layers not in the map?
echo "Object not found";
echo "ERROR: " . $onfe->GetMessage() . "\n";
echo $onfe->GetDetails() . "\n";
echo $onfe->GetStackTrace() . "\n";
} catch (MgException $e) {
//what should we do with general exceptions?
echo "/*general exception:";
echo "ERROR: " . $e->GetMessage();
echo $e->GetDetails() . "*/";
}
}
if ($bExtendSelection) {
$selection = new MgSelection($map);
$queryOptions = new MgFeatureQueryOptions();
$layers = $map->GetLayers();
foreach($aLayers as $szLayer => $aLayer) {
$oLayer = $layers->GetItem($szLayer);
foreach($aLayer as $szClass => $aFilter) {
/* get the feature source from the layer */
$featureResId = new MgResourceIdentifier($oLayer->GetFeatureSourceId());
$featureGeometryName = $oLayer->GetFeatureGeometryName();
$szFilter = implode(' OR ', $aFilter);
$queryOptions->setFilter($szFilter);
/* the class that is used for this layer will be used to select
features */
$class = $oLayer->GetFeatureClassName();
/* select the features */
$featureReader = $featureService->SelectFeatures($featureResId, $class, $queryOptions);
$selection->AddFeatures($oLayer, $featureReader, $maxFeatures);
$layerName = $oLayer->GetName();
if (!in_array($layerName, $properties->layers)) {
array_push($properties->layers, $layerName);
}
$featureReader->Close();
$featureReader = $featureService->SelectFeatures($featureResId, $class, $queryOptions);
$spatialContext = $featureService->GetSpatialContexts($featureResId, true);
$srsLayerWkt = false;
if($spatialContext != null && $spatialContext->ReadNext() != null) {
$srsLayerWkt = $spatialContext->GetCoordinateSystemWkt();
/* skip this layer if the srs is empty */
}
if ($srsLayerWkt == null) {
$srsLayerWkt = $srsDefMap;
}
/* create a coordinate system from the layer's SRS wkt */
$srsLayer = $srsFactory->Create($srsLayerWkt);
// exclude layer if:
// the map is non-arbitrary and the layer is arbitrary or vice-versa
// or
// layer and map are both arbitrary but have different units
//
$bLayerSrsIsArbitrary = ($srsLayer->GetType() == MgCoordinateSystemType::Arbitrary);
$bMapSrsIsArbitrary = ($srsMap->GetType() == MgCoordinateSystemType::Arbitrary);
$bNeedsTransform = false;
if (($bLayerSrsIsArbitrary != $bMapSrsIsArbitrary) ||
($bLayerSrsIsArbitrary && ($srsLayer->GetUnits() != $srsMap->GetUnits()))) {
$bComputedProperties = false;
} else {
$srsTarget = null;
$srsXform = null;
$bNeedsTransform = ($srsLayer->GetUnitScale() != 1.0);
}
$properties = BuildSelectionArray($featureReader, $layerName, $properties,
$bComputedProperties,
$srsLayer, $bNeedsTransform, $oLayer);
$featureReader->Close();
}
}
}
$selection->Save($resourceService, $mapName);
//print_r($properties);
//echo "/* SelectionXML:".$selection->ToXML()."*/";
header('Content-type: text/x-json');
header('X-JSON: true');
$layers = $selection->GetLayers();
$result = NULL;
$result->hasSelection = false;
if ($layers && $layers->GetCount() >= 0)
{
$result->hasSelection = true;
$oExtents = $selection->GetExtents($featureService);
if ($oExtents)
{
$oMin = $oExtents->GetLowerLeftCoordinate();
$oMax = $oExtents->GetUpperRightCoordinate();
$result->extents = NULL;
$result->extents->minx = $oMin->GetX();
$result->extents->miny = $oMin->GetY();
$result->extents->maxx = $oMax->GetX();
$result->extents->maxy = $oMax->GetY();
/*keep the full extents of the selection when saving the selection in the session*/
$properties->extents = NULL;
$properties->extents->minx = $oMin->GetX();
$properties->extents->miny = $oMin->GetY();
$properties->extents->maxx = $oMax->GetX();
$properties->extents->maxy = $oMax->GetY();
}
$result->layers = array();
for ($i=0; $i<$layers->GetCount(); $i++) {
$layer = $layers->GetItem($i);
$layerName = $layer->GetName();
array_push($result->layers, $layerName);
$layerClassName = $layer->GetFeatureClassName();
$filter = $selection->GenerateFilter($layer, $layerClassName);
$a = explode('OR', $filter);
$result->$layerName->featureCount = count($a);
}
/*save selection in the session*/
$_SESSION['selection_array'] = $properties;
}
echo var2json($result);
}
catch (MgException $e)
{
echo "ERROR: " . $e->GetMessage() . "\n";
echo $e->GetDetails() . "\n";
echo $e->GetStackTrace() . "\n";
}
function selectionToArray($selection, $aLayers, $bToggle = true) {
$layers = $selection->GetLayers();
if ($layers)
{
for ($i = 0; $i < $layers->GetCount(); $i++)
{
$layer = $layers->GetItem($i);
if ($layer)
{
$objId = $layer->GetName();
if (!array_key_exists($objId,$aLayers)) {
$aLayers[$objId] = array();
}
$layerClassName = $layer->GetFeatureClassName();
if (!array_key_exists($layerClassName, $aLayers[$objId])) {
$aLayers[$objId][$layerClassName] = array();
}
$selectionString = $selection->GenerateFilter($layer, $layerClassName);
$aFilters = explode('OR', $selectionString);
foreach($aFilters as $filter) {
$filter = trim($filter);
$key = array_search($filter, $aLayers[$objId][$layerClassName]);
if ($key !== false) {
unset($aLayers[$objId][$layerClassName][$key]);
} else {
array_push($aLayers[$objId][$layerClassName], $filter);
}
}
}
}
}
return $aLayers;
}
?>