public function SelectLayerFeatures($ldfId, $format) { //Check for unsupported representations $fmt = $this->ValidateRepresentation($format, array("xml", "geojson", "html", "czml")); $mimeType = $this->GetMimeTypeForFormat($fmt); try { $sessionId = ""; if ($ldfId->GetRepositoryType() == MgRepositoryType::Session) { $sessionId = $ldfId->GetRepositoryName(); } $this->EnsureAuthenticationForSite($sessionId, true, $mimeType); $siteConn = new MgSiteConnection(); $siteConn->Open($this->userInfo); $featSvc = $siteConn->CreateService(MgServiceType::FeatureService); $query = new MgFeatureQueryOptions(); $propList = $this->GetRequestParameter("properties", ""); $filter = $this->GetRequestParameter("filter", ""); $orderby = $this->GetRequestParameter("orderby", ""); $orderOptions = $this->GetRequestParameter("orderoption", ""); $maxFeatures = $this->GetRequestParameter("maxfeatures", ""); $transformto = $this->GetRequestParameter("transformto", ""); $bbox = $this->GetRequestParameter("bbox", ""); $pageSize = $this->GetRequestParameter("pagesize", -1); $pageNo = $this->GetRequestParameter("page", -1); //Internal debugging flag $chunk = $this->GetBooleanRequestParameter("chunk", true); if ($pageNo >= 0 && $pageSize === -1) { $this->BadRequest($this->app->localizer->getText("E_MISSING_REQUIRED_PARAMETER", "pagesize"), $mimeType); } else { //The way that CZML output is done means we cannot support pagination if ($pageNo >= 0 && $pageSize > 0 && $fmt === "czml") { $this->BadRequest($this->app->localizer->getText("E_CZML_PAGINATION_NOT_SUPPORTED"), $mimeType); } } $limit = -1; if ($maxFeatures !== "") { $limit = intval($maxFeatures); } //Load the Layer Definition document and extract the relevant bits of information //we're interested in $resSvc = $siteConn->CreateService(MgServiceType::ResourceService); $ldfContent = $resSvc->GetResourceContent($ldfId); $doc = new DOMDocument(); $doc->loadXML($ldfContent->ToString()); $vl = $doc->getElementsByTagName("VectorLayerDefinition"); if ($vl->length == 1) { $vlNode = $vl->item(0); $fsId = $vlNode->getElementsByTagName("ResourceId"); $fc = $vlNode->getElementsByTagName("FeatureName"); $hlink = $vlNode->getElementsByTagName("Url"); $tt = $vlNode->getElementsByTagName("ToolTip"); $flt = $vlNode->getElementsByTagName("Filter"); $elev = $vlNode->getElementsByTagName("ElevationSettings"); if ($fsId->length == 1) { $fsId = new MgResourceIdentifier($fsId->item(0)->nodeValue); $site = $siteConn->GetSite(); $this->VerifyWhitelist($fsId->ToString(), $this->GetMimeTypeForFormat($fmt), "SELECTFEATURES", $fmt, $site, $this->userName); if ($fc->length == 1) { //Add hyperlink, tooltip and elevation as special computed properties if ($hlink->length == 1 && strlen($hlink->item(0)->nodeValue) > 0) { $query->AddComputedProperty(MgRestConstants::PROP_HYPERLINK, $hlink->item(0)->nodeValue); } if ($tt->length == 1 && strlen($tt->item(0)->nodeValue) > 0) { $query->AddComputedProperty(MgRestConstants::PROP_TOOLTIP, $tt->item(0)->nodeValue); } if ($elev->length == 1) { $elevNode = $elev->item(0); $zoff = $elevNode->getElementsByTagName("ZOffset"); $zofftype = $elevNode->getElementsByTagName("ZOffsetType"); $zext = $elevNode->getElementsByTagName("ZExtrusion"); $unit = $elevNode->getElementsByTagName("Unit"); if ($zoff->length == 1 && strlen($zoff->item(0)->nodeValue) > 0) { $query->AddComputedProperty(MgRestConstants::PROP_Z_OFFSET, $zoff->item(0)->nodeValue); } else { $query->AddComputedProperty(MgRestConstants::PROP_Z_OFFSET, "0"); } if ($zofftype->length == 1 && strlen($zofftype->item(0)->nodeValue) > 0) { $query->AddComputedProperty(MgRestConstants::PROP_Z_OFFSET_TYPE, "'" . $zofftype->item(0)->nodeValue . "'"); } else { $query->AddComputedProperty(MgRestConstants::PROP_Z_OFFSET_TYPE, "'RelativeToGround'"); } if ($zext->length == 1 && strlen($zext->item(0)->nodeValue) > 0) { $query->AddComputedProperty(MgRestConstants::PROP_Z_EXTRUSION, $zext->item(0)->nodeValue); } else { $query->AddComputedProperty(MgRestConstants::PROP_Z_EXTRUSION, "0"); } if ($unit->length == 1 && strlen($unit->item(0)->nodeValue) > 0) { $query->AddComputedProperty(MgRestConstants::PROP_Z_UNITS, "'" . $unit->item(0)->nodeValue . "'"); } else { $query->AddComputedProperty(MgRestConstants::PROP_Z_UNITS, "'Meters'"); } } $baseFilter = ""; //Set filter from layer if defined if ($flt->length == 1 && strlen($flt->item(0)->nodeValue) > 0) { if ($filter !== "") { //logical AND with the layer's filter to combine them $baseFilter = "(" . $flt->item(0)->nodeValue . ") AND (" . $filter . ")"; $query->SetFilter($baseFilter); } else { $baseFilter = $flt->item(0)->nodeValue; $query->SetFilter($baseFilter); } } else { if ($filter !== "") { $baseFilter = $filter; $query->SetFilter($baseFilter); } } $tokens = explode(":", $fc->item(0)->nodeValue); $schemaName = $tokens[0]; $className = $tokens[1]; $clsDef = NULL; //Unless an explicit property list has been specified, we're explicitly adding all properties //from the class definition if ($propList !== "") { $propNames = explode(",", $propList); //If you have a comma in your property names, it's your own fault :) foreach ($propNames as $propName) { $query->AddFeatureProperty($propName); } } else { if ($clsDef == NULL) { $clsDef = $featSvc->GetClassDefinition($fsId, $schemaName, $className); } $clsProps = $clsDef->GetProperties(); for ($i = 0; $i < $clsProps->GetCount(); $i++) { $propDef = $clsProps->GetItem($i); $query->AddFeatureProperty($propDef->GetName()); } } if ($orderby !== "") { $orderPropNames = explode(",", $orderby); //If you have a comma in your property names, it's your own fault :) $orderProps = new MgStringCollection(); foreach ($orderPropNames as $propName) { $orderProps->Add($propName); } $orderOpt = MgOrderingOption::Ascending; if (strtolower($orderOptions) === "desc") { $orderOpt = MgOrderingOption::Descending; } $query->SetOrderingFilter($orderProps, $orderOpt); } //We must require features as LL84 for CZML output if ($fmt == "czml") { $transformto = "LL84"; } $transform = null; if ($transformto !== "") { $transform = MgUtils::GetTransform($featSvc, $fsId, $schemaName, $className, $transformto); } if ($bbox !== "") { $parts = explode(",", $bbox); if (count($parts) == 4) { $wktRw = new MgWktReaderWriter(); if ($clsDef == NULL) { $clsDef = $featSvc->GetClassDefinition($fsId, $schemaName, $className); } $geom = $wktRw->Read(MgUtils::MakeWktPolygon($parts[0], $parts[1], $parts[2], $parts[3])); //Transform bbox to target cs if flag specified $bboxIsTargetCs = $this->GetBooleanRequestParameter("bboxistargetcs", false); if ($bboxIsTargetCs) { //Because it has been declared the bbox is in target coordiantes, we have to transform that bbox back to the //source, which means we need an inverse transform $invTx = MgUtils::GetTransform($featSvc, $fsId, $schemaName, $className, $transformto, true); $geom = $geom->Transform($invTx); } $query->SetSpatialFilter($clsDef->GetDefaultGeometryPropertyName(), $geom, MgFeatureSpatialOperations::EnvelopeIntersects); } } //Ensure valid page number if specified if ($pageSize > 0) { if ($pageNo < 1) { $pageNo = 1; } } $owriter = null; if ($chunk === "0") { $owriter = new MgSlimChunkWriter($this->app); } else { $owriter = new MgHttpChunkWriter(); } if ($fmt == "czml") { $result = new MgCzmlResult($featSvc, $fsId, "{$schemaName}:{$className}", $query, $limit, $baseFilter, $vlNode, $owriter); $result->CheckAndSetDownloadHeaders($this->app, $format); if ($transform != null) { $result->SetTransform($transform); } $result->Output($format); } else { $reader = $featSvc->SelectFeatures($fsId, "{$schemaName}:{$className}", $query); if ($pageSize > 0) { $pageReader = new MgPaginatedFeatureReader($reader, $pageSize, $pageNo, $limit); $result = new MgReaderChunkedResult($featSvc, $pageReader, $limit, $owriter, $this->app->localizer); } else { $result = new MgReaderChunkedResult($featSvc, $reader, $limit, $owriter, $this->app->localizer); } $result->CheckAndSetDownloadHeaders($this->app, $format); if ($transform != null) { $result->SetTransform($transform); } if ($fmt === "html") { $result->SetHtmlParams($this->app); } $result->Output($format); } } else { throw new Exception($this->app->localizer->getText("E_LAYER_HAS_INVALID_FEATURE_CLASS", $ldfId->ToString())); } } else { throw new Exception($this->app->localizer->getText("E_LAYER_HAS_INVALID_FEATURE_SOURCE", $ldfId->ToString())); } } } catch (MgException $ex) { $this->OnException($ex, $mimeType); } }
function ValidateResourceId($proposedResourceId) { $validResourceId = ""; try { $resId = new MgResourceIdentifier($proposedResourceId); $validResourceId = $resId->ToString(); } catch (MgException $ex) { $validResourceId = ""; } return $validResourceId; }
function DownloadMarkup() { $resourceService = $this->site->CreateService(MgServiceType::ResourceService); $featureService = $this->site->CreateService(MgServiceType::FeatureService); $markupLayerResId = new MgResourceIdentifier($this->args['MARKUPLAYER']); $markupFsId = new MgResourceIdentifier($this->GetResourceIdPrefix() . $markupLayerResId->GetName() . '.FeatureSource'); $extension = $this->GetFileExtension($markupLayerResId->ToString()); if (strcmp($extension, ".zip") == 0) { $dataList = $resourceService->EnumerateResourceData($markupFsId); $doc = DOMDocument::LoadXML($dataList->ToString()); $dataItems = $doc->getElementsByTagName("Name"); $tmpFiles = array(); //Copy out all data files to a temp location for ($i = 0; $i < $dataItems->length; $i++) { $dataName = $dataItems->item($i)->nodeValue; $byteReader = $resourceService->GetResourceData($markupFsId, $dataName); //Sink to temp file $tmpSink = new MgByteSink($byteReader); $fileName = tempnam(sys_get_temp_dir(), $dataName); $tmpSink->ToFile($fileName); $tmpFiles[$dataName] = $fileName; } //Zip them up. $zipName = $markupLayerResId->GetName() . $extension; $zipPath = tempnam(sys_get_temp_dir(), $zipName); $zip = new ZipArchive(); $zip->open($zipPath, ZIPARCHIVE::CREATE); foreach ($tmpFiles as $dataName => $filePath) { $dataNorm = strtolower($dataName); //HACK: There must be some defect in MgFeatureService::CreateFeatureSource() for SHP //files or the FDO provider, because even if we plug in a coord sys WKT when we create //it, we get a blank prj file (both Windows/Linux). Re-uploading this same zip file back into //the widget causes problems in Linux (markup features not rendered) because of the blank prj. // //So that's the problem. Here's the workaround: If we find a blank prj file as we're assembling //the zip file for download, pump our current Map's WKT into the prj file before packaging it up // //That's what we were already doing when we called MgFeatureService::CreateFeatureSource(), but it //or the provider didn't like it. if (substr($dataNorm, strlen($dataNorm) - strlen("prj")) == "prj") { $content = file_get_contents($filePath); if (strlen($content) == 0) { $map = new MgMap(); $map->Open($resourceService, $this->args['MAPNAME']); $content = $map->GetMapSRS(); file_put_contents($filePath, $content); } } $zip->addFile($filePath, $dataName); } $zip->close(); //Serve it up for download $bs = new MgByteSource($zipPath); $br = $bs->GetReader(); $len = $br->GetLength(); $outputBuffer = ''; $buffer = ''; while ($br->Read($buffer, 50000) != 0) { $outputBuffer .= $buffer; } header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename={$zipName}"); header("Content-Length: " . strlen($outputBuffer)); echo $outputBuffer; //Let's be nice and clean up after ourselves unlink($zipPath); foreach ($tmpFiles as $dataName => $filePath) { unlink($filePath); } } else { //Single file, make things easier! $dataName = $markupLayerResId->GetName() . $extension; $byteReader = $resourceService->GetResourceData($markupFsId, $dataName); $len = $byteReader->GetLength(); $outputBuffer = ''; $buffer = ''; while ($byteReader->Read($buffer, 50000) != 0) { $outputBuffer .= $buffer; } header("Content-Type: " . $byteReader->GetMimeType()); header("Content-Disposition: attachment; filename={$dataName}"); header("Content-Length: " . strlen($outputBuffer)); echo $outputBuffer; } }