<?php /** * Buffer * * $Id$ * * Copyright (c) 2007, DM Solutions Group Inc. * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /***************************************************************************** * Purpose: Buffer selected features *****************************************************************************/ include ('Common.php'); include ('Utilities.php'); try { header('content-type: text/xml'); if (!isset($_REQUEST['session']) || !isset($_REQUEST['mapname']) || !isset($_REQUEST['layer']) || !isset($_REQUEST['fillcolor']) || !isset($_REQUEST['bordercolor']) || !isset($_REQUEST['distance'])) { echo "<Error>Arguments missing </Error>"; exit; } /* if merge is set, buffer the entire selection as one instead of creating buffers * on each selected feature */ $merge = ((isset($_REQUEST['merge'])) && $_REQUEST['merge'] == 1)?true:false; $layerName = $_REQUEST['layer']; $distance = $_REQUEST['distance']; $fillColor = $_REQUEST['fillcolor']; $borderColor = $_REQUEST['bordercolor']; $schemaName = 'BufferSchema'; $map = new MgMap(); $map->Open($resourceService, $mapName); /* Get the map SRS - we use this to convert distances */ $srsFactory = new MgCoordinateSystemFactory(); //safely get an SRS ... (in Utilities) $srsDefMap = GetMapSRS($map); $mapSrsUnits = ""; $srsMap = $srsFactory->Create($srsDefMap); $arbitraryMapSrs = ($srsMap->GetType() == MgCoordinateSystemType::Arbitrary); if($arbitraryMapSrs) $mapSrsUnits = $srsMap->GetUnits(); $featureService = $siteConnection->CreateService(MgServiceType::FeatureService); $agfRW = new MgAgfReaderWriter(); $layers = $map->GetLayers(); try { /* if the layer already exists, we'll clear the existing features * from it and reset the content */ $bValidLayer = false; $j = 2; while(!$bValidLayer) { $layer = $layers->GetItem($layerName); $featureClassName = $layer->GetFeatureClassName(); if ($featureClassName != $schemaName.':'.$layerName) { $layerName = $layerName . ' (' . $j . ')'; } else { $bValidLayer = true; } } $layerId = $layer->GetLayerDefinition(); $featureSourceName = $layer->GetFeatureSourceId(); $featureSourceId = new MgResourceIdentifier($featureSourceName); ClearFeatureSource($featureService, $featureSourceId, $featureClassName); BuildLayerContent($resourceService, $layerId, $featureSourceName, $schemaName, $layerName, $fillColor, $borderColor); } catch (MgObjectNotFoundException $nfe) { $featureSourceName = "Session:".$sessionID."//".$layerName.".FeatureSource"; $featureSourceId = new MgResourceIdentifier($featureSourceName); CreateFeatureSource($map, $featureSourceId, $layerName, $featureService, MgFeatureGeometricType::Surface, $schemaName); //create the output layer definition of poylgon type $layerDefinition = "Session:".$sessionID."//". $layerName.".LayerDefinition"; $layerId = new MgResourceIdentifier($layerDefinition); BuildLayerContent($resourceService, $layerId, $featureSourceName, $schemaName, $layerName, $fillColor, $borderColor); $layer = new MGLayer($layerId, $resourceService); $layer->SetName($layerName); $layer->SetLegendLabel($layerName); $layer->SetDisplayInLegend(true); $layer->SetSelectable(true); $layers->Insert(0, $layer); } //loop through the selection of the input layer. If no selection, select all features $queryOptions = new MgFeatureQueryOptions(); $selection = new MgSelection($map); $selection->Open($resourceService, $mapName); $selLayers = $selection->GetLayers(); /* if we are merging, put all the geometries into a single geometry collection */ $inputGeometries = new MgGeometryCollection(); /* store the insert commands for creating buffers */ $oCommandsColl = new MgFeatureCommandCollection(); $nCount = $selLayers->GetCount(); for ($i=0; $i<$nCount; $i++) { $selLayer = $selLayers->GetItem($i); $featureClassName = $selLayer->GetFeatureClassName(); $filter = $selection->GenerateFilter($selLayer, $featureClassName); if ($filter == '') { continue; } $queryOptions->SetFilter($filter); $featureSource = new MgResourceIdentifier($selLayer->GetFeatureSourceId()); $featureReader = $featureService->SelectFeatures($featureSource, $featureClassName, $queryOptions); $classDef = $featureReader->GetClassDefinition(); $geomPropName = $classDef->GetDefaultGeometryPropertyName(); /* figure out the layer SRS - taken from buffer.php in * original mapguide ajax viewer * * The layer may be excluded if it doesn't meet some specific * needs ... commented inline below */ $spatialContext = $featureService->GetSpatialContexts($featureSource, true); $layerSrsWkt = ""; if($spatialContext != null) { $spatialContext->ReadNext(); $layerSrsWkt = $spatialContext->GetCoordinateSystemWkt(); /* skip this layer if the srs is empty */ if($layerSrsWkt == "") { continue; } } else { /* skip this layer if there is no spatial context at all */ continue; } /* create a coordinate system from the layer's SRS wkt */ $layerCs = $srsFactory->Create($layerSrsWkt); $arbitraryDsSrs = ($layerCs->GetType() == MgCoordinateSystemType::Arbitrary); $dsSrsUnits = ""; if($arbitraryDsSrs) { $dsSrsUnits = $srsDs->GetUnits(); } // 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 // if(($arbitraryDsSrs != $arbitraryMapSrs) || ($arbitraryDsSrs && ($dsSrsUnits != $mapSrsUnits))) { continue; } // calculate distance in the data source SRS units // $dist = $layerCs->ConvertMetersToCoordinateSystemUnits($distance); // calculate great circle unless data source srs is arbitrary $verMajor = subStr(GetSiteVersion(), 0,1); if(!$arbitraryDsSrs) { if ($verMajor == '1') { $measure = new MgCoordinateSystemMeasure($layerCs); } else { $measure = $layerCs->GetMeasure(); } } else { $measure = null; } // create a SRS transformer if necessary. if($layerSrsWkt != $srsDefMap) { if ($verMajor == '1') { $srsXform = new MgCoordinateSystemTransform($layerCs, $srsMap); } else { $srsXform = $srsFactory->GetTransform($layerCs, $srsMap); } } else { $srsXform = null; } while ($featureReader->ReadNext()) { $oGeomAgf = $featureReader->GetGeometry($geomPropName); $oGeom = $agfRW->Read($oGeomAgf); $wktReaderWriter = new MgWktReaderWriter(); $agfTextPoint = $wktReaderWriter->Write($oGeom); //echo "<!-- wkt: ".$agfTextPoint." -->\n"; if (!$merge) { /* use measure to accomodate differences in SRS */ $oNewGeom = $oGeom->Buffer($dist, $measure); $geomProp = new MgGeometryProperty("GEOM", $agfRW->Write($oNewGeom)); $oPropertyColl = new MgPropertyCollection(); $oPropertyColl->Add($geomProp); $oCommandsColl->Add(new MgInsertFeatures($schemaName.':'.$layerName, $oPropertyColl)); } else { if ($srsXform == null) { $oNewGeom = $oGeom; } else { $oNewGeom = $oGeom->Transform($srsXform); } $inputGeometries->Add($oNewGeom); } } $featureReader->Close(); } if($merge) { if($inputGeometries->GetCount() > 0) { $dist = $srsMap->ConvertMetersToCoordinateSystemUnits($distance); if(!$arbitraryMapSrs) { $verMajor = subStr(GetSiteVersion(), 0,1); if ($verMajor == '1') { $measure = new MgCoordinateSystemMeasure($srsMap); } else { $measure = $srsMap->GetMeasure(); } } else { $measure = null; } $geomFactory = new MgGeometryFactory(); $oGeom = $geomFactory->CreateMultiGeometry($inputGeometries); $oNewGeom = $oGeom->Buffer($dist, $measure); $geomProp = new MgGeometryProperty("GEOM", $agfRW->Write($oNewGeom)); $oPropertyColl = new MgPropertyCollection(); $oPropertyColl->Add($geomProp); $oCommandsColl->Add(new MgInsertFeatures($schemaName.':'.$layerName, $oPropertyColl)); } } $result = $featureService->UpdateFeatures($featureSourceId, $oCommandsColl, false); $layer->ForceRefresh(); $map->Save($resourceService); echo "<Buffer>"; echo "<Layer>".$layerId->ToString(); echo "</Layer>"; echo "</Buffer>"; } catch (MgException $e) { echo "last error"; echo "ERROR: " . $e->GetMessage() . "\n"; echo $e->GetDetails() . "\n"; echo $e->GetStackTrace() . "\n"; } function BuildLayerContent($resourceService, $layerId, $featureSourceName, $schemaName, $layerName, $fillColor, $borderColor) { $layerContent = '<?xml version="1.0" encoding="UTF-8"?> <LayerDefinition version="1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="LayerDefinition-1.0.0.xsd"> <VectorLayerDefinition> <ResourceId>%s</ResourceId> <FeatureName>%s:%s</FeatureName> <FeatureNameType>FeatureClass</FeatureNameType> <Geometry>GEOM</Geometry> <VectorScaleRange> <AreaTypeStyle> <AreaRule> <LegendLabel/> <AreaSymbolization2D> <Fill> <FillPattern>Solid</FillPattern> <ForegroundColor>%s</ForegroundColor> <BackgroundColor>FF000000</BackgroundColor> </Fill> <Stroke> <LineStyle>Solid</LineStyle> <Thickness>0</Thickness> <Color>%s</Color> <Unit>Points</Unit> </Stroke> </AreaSymbolization2D> </AreaRule> </AreaTypeStyle> </VectorScaleRange> </VectorLayerDefinition> </LayerDefinition> '; $layerContent = sprintf($layerContent, $featureSourceName, $schemaName, $layerName, $fillColor, $borderColor); $oByteSource = new MGByteSource($layerContent, strlen($layerContent)); $resourceService->SetResource($layerId, $oByteSource->GetReader(), null); } ?>