SetClientIp(GetClientIp()); $cred->SetClientAgent(GetClientAgent()); //connect to the site and get a feature service and a resource service instances $site = new MgSiteConnection(); $site->Open($cred); $featureSrvc = $site->CreateService(MgServiceType::FeatureService); $resourceSrvc = $site->CreateService(MgServiceType::ResourceService); $dataSourceId = new MgResourceIdentifier($dataSource); $layerDefId = new MgResourceIdentifier($layerDef); //load the map runtime state and locate the measure layer // $map = new MgMap($site); $map->Open($mapName); $layers = $map->GetLayers(); $srs = GetMapSrs($map); $layer = FindLayer($layers, $layerDef); if($clear) { $total = 0; if($layer != null) $layers->Remove($layer); if(DataSourceExists($resourceSrvc, $dataSourceId)) ClearDataSource($featureSrvc, $dataSourceId, $featureName); } else { $srsFactory = new MgCoordinateSystemFactory(); $srsMap = $srsFactory->Create($srs); $srsType = $srsMap->GetType(); if($srsType == MgCoordinateSystemType::Geographic) $distance = $srsMap->MeasureGreatCircleDistance($x1, $y1, $x2, $y2); else $distance = $srsMap->MeasureEuclideanDistance($x1, $y1, $x2, $y2); $distance = $srsMap->ConvertCoordinateSystemUnitsToMeters($distance); if ($units == "mi") $distance *= 0.000621371192; //get miles if ($units == "km") $distance *= 0.001; //get kilometers if ($units == "ft") $distance *= 3.2808399; //get feet if ($units == "usft") $distance *= 3.2808333; //get US survey feet $total += $distance; //create the line string geometry representing this segment // $geomFactory = new MgGeometryFactory(); $coordinates = new MgCoordinateCollection(); $coordinates->Add($geomFactory->CreateCoordinateXY($x1, $y1)); $coordinates->Add($geomFactory->CreateCoordinateXY($x2, $y2)); $geom = $geomFactory->CreateLineString($coordinates); if($segId == 1) { //first segment // if(!DataSourceExists($resourceSrvc, $dataSourceId)) { //create feature source // $classDef = new MgClassDefinition(); $classDef->SetName($featureName); $classDef->SetDescription(GetLocalizedString("MEASUREFEATURECLASS", $locale)); $classDef->SetDefaultGeometryPropertyName("GEOM"); //Set KEY property $prop = new MgDataPropertyDefinition("KEY"); $prop->SetDataType(MgPropertyType::Int32); $prop->SetAutoGeneration(true); $prop->SetReadOnly(true); $classDef->GetIdentityProperties()->Add($prop); $classDef->GetProperties()->Add($prop); //Set PARTIAL property. Hold the distance for this segment $prop = new MgDataPropertyDefinition("PARTIAL"); $prop->SetDataType(MgPropertyType::Double); $classDef->GetProperties()->Add($prop); //Set TOTAL property. Hold the total distance up to this segment, including it $prop = new MgDataPropertyDefinition("TOTAL"); $prop->SetDataType(MgPropertyType::Double); $classDef->GetProperties()->Add($prop); //Set geometry property $prop = new MgGeometricPropertyDefinition("GEOM"); //$prop->SetGeometryTypes(MgFeatureGeometricType::mfgtSurface); //TODO use the constant when exposed $prop->SetGeometryTypes(4); $classDef->GetProperties()->Add($prop); //Create the schema $schema = new MgFeatureSchema("MeasureSchema", GetLocalizedString("MEASURESCHEMADESCR", $locale)); $schema->GetClasses()->Add($classDef); //finally, creation of the feature source $params = new MgFileFeatureSourceParams("OSGeo.SDF", "MapSrs", $srs, $schema); $featureSrvc->CreateFeatureSource($dataSourceId, $params); //build map tip $unitText = ""; if ($units == "mi") $unitText = "DISTANCEMILES"; if ($units == "km") $unitText = "DISTANCEKILOMETERS"; if ($units == "ft") $unitText = "DISTANCEFEET"; if ($units == "usft") $unitText = "DISTANCEUSFEET"; if ($units == "m") $unitText = "DISTANCEMETERS"; $unitText = GetLocalizedString($unitText, $locale); $tip = sprintf("Concat(Concat(Concat('" . GetLocalizedString("MEASUREPARTIAL", $locale) . ": ', PARTIAL), Concat(', " . GetLocalizedString("MEASURETOTAL", $locale) . ": ', TOTAL)), ' (%s)')", $unitText); //Create the layer definition $layerDefContent = BuildLayerDefinitionContent($dataSource, $featureName, $tip); $resourceSrvc->SetResource($layerDefId, $layerDefContent, null); } else { //data source already exist. clear its content ClearDataSource($featureSrvc, $dataSourceId, $featureName); } //Add the layer to the map, if it's not already in it if($layer == null) { $legendName = GetLocalizedString("MEASURELAYER", $locale); $layer = new MgLayer($layerDefId, $resourceSrvc); $layer->SetDisplayInLegend(true); $layer->SetLegendLabel($legendName); $layers->Insert(0, $layer); } } // create a feature representing this segment and insert it into the data source // $measureProps = new MgPropertyCollection(); $partialProp = new MgDoubleProperty("PARTIAL", $distance); $measureProps->Add($partialProp); $totalProp = new MgDoubleProperty("TOTAL", $total); $measureProps->Add($totalProp); $agf = new MgAgfReaderWriter(); $geomReader = $agf->Write($geom); $geomProp = new MgGeometryProperty("GEOM", $geomReader); $measureProps->Add($geomProp); $cmd = new MgInsertFeatures($featureName, $measureProps); $commands = new MgFeatureCommandCollection(); $commands->Add($cmd); ReleaseReader($featureSrvc->UpdateFeatures($dataSourceId, $commands, false)); } if($layer != null) $layer->ForceRefresh(); $map->Save(); } catch(MgException $e) { OnError(GetLocalizedString("MEASUREERROR", $locale), $e->GetDetails()); return; } catch(Exception $ne) { OnError(GetLocalizedString("MEASUREERROR", $locale), $ne->getMessage()); return; } $templ = file_get_contents("../viewerfiles/measureui.templ"); $templ = Localize($templ, $locale, GetClientOS()); $vpath = GetSurroundVirtualPath(); print sprintf($templ, $locale, $target, $popup, $mapName, $sessionId, $total, $distance, 1, $units, $vpath . "measure.php", $vpath . "measure.php"); function OnError($title, $msg) { global $target, $popup; $templ = Localize(file_get_contents("../viewerfiles/errorpage.templ"), $locale, GetClientOS()); print sprintf($templ, $popup, $title, $msg); } function DataSourceExists($resourceSrvc, $dataSourceId) { return $resourceSrvc->ResourceExists($dataSourceId); } function BuildLayerDefinitionContent($dataSource, $featureName, $tip) { $layerTempl = file_get_contents("../viewerfiles/linelayerdef.templ"); $xmlStr = sprintf($layerTempl, $dataSource, $featureName, "GEOM", $tip, 1, "ff0000"); $src = new MgByteSource($xmlStr, strlen($xmlStr)); return $src->GetReader(); } function ClearDataSource($featureSrvc, $dataSourceId, $featureName) { $deleteCmd = new MgDeleteFeatures($featureName, "KEY >= 0"); $commands = new MgFeatureCommandCollection(); $commands->Add($deleteCmd); $featureSrvc->UpdateFeatures($dataSourceId, $commands, false); } function FindLayer($layers, $layerDef) { $layer = null; for($i = 0; $i < $layers->GetCount(); $i++) { $layer1 = $layers->GetItem($i); if($layer1->GetLayerDefinition()->ToString() == $layerDef) { $layer = $layer1; break; } } return $layer; } function GetParameters($params) { global $mapName, $sessionId, $x1, $y1, $x2, $y2, $popup, $units; global $total, $clear, $us, $segId, $target, $locale; $sessionId = ValidateSessionId(GetParameter($params, 'SESSION')); $locale = ValidateLocaleString(GetParameter($params, 'LOCALE')); $mapName = ValidateMapName(GetParameter($params, 'MAPNAME')); $target = GetIntParameter($params, 'TGT'); $popup = GetIntParameter($params, 'POPUP'); $units = GetParameter($params, 'UNITS'); if(isset($params['CLEAR'])) $clear = true; else { $segId = GetIntParameter($params, 'SEGID'); $x1 = GetDoubleParameter($params, 'X1'); $y1 = GetDoubleParameter($params, 'Y1'); $x2 = GetDoubleParameter($params, 'X2'); $y2 = GetDoubleParameter($params, 'Y2'); $total = GetDoubleParameter($params, 'TOTAL'); } } function GetRequestParameters() { if($_SERVER['REQUEST_METHOD'] == "POST") GetParameters($_POST); else GetParameters($_GET); } function GetMapSrs($map) { $srs = $map->GetMapSRS(); if($srs != "") return $srs; //SRS is currently optional. Waiting for this to change, set the default SRS to ArbitrayXY meters // return "LOCALCS[\"Non-Earth (Meter)\",LOCAL_DATUM[\"Local Datum\",0],UNIT[\"Meter\", 1],AXIS[\"X\",EAST],AXIS[\"Y\",NORTH]]"; } function ReleaseReader($res) { if($res == null) return; $prop = $res->GetItem(0); if($prop == null) return; if ($prop instanceof MgStringProperty) throw new Exception($prop->GetValue()); $reader = $prop->GetValue(); if($reader == null) return; $reader->Close(); } ?>