protected function parameters() { switch ($this->action) { case self::ACTION_PLACEMARKS: $fields = $this->parser->getFieldKeys(); $params = array('text' => '%', 'inSR' => $this->parser->getProjection(), 'spatialRel' => 'esriSpatialRelIntersects', 'where' => '', 'returnGeometry' => 'true', 'outSR' => '', 'outFields' => implode(',', $fields), 'f' => 'json'); if ($this->useExtentGeometry) { $extent = $this->parser->getExtent(); $bbox = $extent['xmin'] . ',' . $extent['ymin'] . ',' . $extent['xmax'] . ',' . $extent['ymax']; $params['text'] = ''; $params['geometry'] = $bbox; $params['geometryType'] = 'esriGeometryEnvelope'; } if ($this->orderByFields) { $params['where'] = 'OBJECTID>0'; $params['orderByFields'] = $this->orderByFields; } return $params; case self::ACTION_SEARCH: $displayField = null; if (isset($this->selectedLayer)) { $displayField = $this->parser->getDisplayFieldForFolder($this->selectedLayer); } if ($displayField) { $searchText = strtoupper(str_replace("'", "''", $this->searchFilters['text'])); return array('where' => "UPPER({$displayField}) LIKE '%{$searchText}%'", 'f' => 'json'); } else { return array('text' => str_replace("'", "''", $this->searchFilters['text']), 'f' => 'json'); } case self::ACTION_SEARCH_NEARBY: $bbox = normalizedBoundingBox($this->searchFilters['center'], $this->searchFilters['tolerance'], null, $this->parser->getProjection()); return array('spatialRel' => 'esriSpatialRelIntersects', 'geometryType' => 'esriGeometryEnvelope', 'geometry' => "{$bbox['min']['lon']},{$bbox['min']['lat']},{$bbox['max']['lon']},{$bbox['max']['lat']}", 'f' => 'json'); } return parent::parameters(); }
public function searchByProximity($center, $tolerance, $maxItems = null) { $this->setupProjector(); $bbox = normalizedBoundingBox($center, $tolerance, null, null); $results = array(); foreach ($this->getAllLeafNodes() as $item) { $geometry = $item->getGeometry(); if ($geometry) { $featureCenter = $geometry->getCenterCoordinate(); if ($this->projector) { $featureCenter = $this->projector->projectPoint($featureCenter); } if ($featureCenter['lat'] <= $bbox['max']['lat'] && $featureCenter['lat'] >= $bbox['min']['lat'] && $featureCenter['lon'] <= $bbox['max']['lon'] && $featureCenter['lon'] >= $bbox['min']['lon']) { $distance = greatCircleDistance($bbox['center']['lat'], $bbox['center']['lon'], $featureCenter['lat'], $featureCenter['lon']); if ($distance > $tolerance) { continue; } // keep keys unique; give priority to whatever came first $intDist = intval($distance * 1000); while (array_key_exists($intDist, $results)) { $intDist += 1; // one centimeter } $item->setField('distance', $distance); $item->addCategoryId($this->categoryId); $results[$intDist] = $this->getProjectedFeature($item); } } } return $results; }
protected function parameters() { switch ($this->action) { case self::ACTION_PLACEMARKS: $fields = $this->parser->getFieldKeys(); $params = array('text' => '%', 'inSR' => $this->parser->getProjection(), 'spatialRel' => 'esriSpatialRelIntersects', 'where' => '1=1', 'orderByFields' => $this->parser->getDisplayFieldForFolder($this->selectedLayer), 'returnGeometry' => 'true', 'outSR' => '', 'outFields' => implode(',', $fields), 'f' => 'json'); if ($this->useExtentGeometry) { $extent = $this->parser->getExtent(); $bbox = $extent['xmin'] . ',' . $extent['ymin'] . ',' . $extent['xmax'] . ',' . $extent['ymax']; $params['text'] = ''; $params['geometry'] = $bbox; $params['geometryType'] = 'esriGeometryEnvelope'; } // If we have order fields, assume they are separated by commas if ($this->orderByFields) { $orderFields = array_map('trim', explode(',', $this->orderByFields)); // take intersection of configured sort fields and existing fields in layer $validFields = array_intersect($orderFields, $fields); // If we have at least one valid field, update the orderByFields to use the valid field(s) if (!empty($validFields)) { $params['orderByFields'] = implode(',', $validFields); } } return $params; case self::ACTION_SEARCH: $displayField = null; if (isset($this->selectedLayer)) { $displayField = $this->parser->getDisplayFieldForFolder($this->selectedLayer); } if ($displayField) { $searchText = strtoupper(str_replace("'", "''", $this->searchFilters['text'])); return array('where' => "UPPER({$displayField}) LIKE '%{$searchText}%'", 'f' => 'json'); } else { return array('text' => str_replace("'", "''", $this->searchFilters['text']), 'f' => 'json'); } case self::ACTION_SEARCH_NEARBY: $bbox = normalizedBoundingBox($this->searchFilters['center'], $this->searchFilters['tolerance'], null, $this->parser->getProjection()); return array('spatialRel' => 'esriSpatialRelIntersects', 'geometryType' => 'esriGeometryEnvelope', 'geometry' => "{$bbox['min']['lon']},{$bbox['min']['lat']},{$bbox['max']['lon']},{$bbox['max']['lat']}", 'f' => 'json'); } return parent::parameters(); }
public function searchByProximity($center, $tolerance = 1000, $maxItems = 0, $dataController = null) { $bbox = normalizedBoundingBox($center, $tolerance, null, null); $params = array($bbox['min']['lat'], $bbox['max']['lat'], $bbox['min']['lon'], $bbox['max']['lon'], $bbox['center']['lat'], $bbox['center']['lat'], $bbox['center']['lon'], $bbox['center']['lon']); $sql = 'SELECT p.*, pc.category_id FROM ' . MapDB::PLACEMARK_TABLE . ' p, ' . MapDB::PLACEMARK_CATEGORY_TABLE . ' pc' . ' WHERE p.placemark_id = pc.placemark_id' . ' AND p.lat = pc.lat AND p.lon = pc.lon' . ' AND p.lat >= ? AND p.lat < ? AND p.lon >= ? AND p.lon < ?' . ' ORDER BY (p.lat - ?)*(p.lat - ?) + (p.lon - ?)*(p.lon - ?)'; $this->getSearchResultsForQuery($sql, $params, $maxItems); $resultsByDistance = array(); foreach ($this->searchResults as $result) { $rCenter = $result->getGeometry()->getCenterCoordinate(); $distance = greatCircleDistance($center['lat'], $center['lon'], $rCenter['lat'], $rCenter['lon']); $result->setField('distance', $distance); // avoid distance collisions while (isset($resultsByDistance[$distance])) { $distance++; } $resultsByDistance[$distance] = $result; } ksort($resultsByDistance); $this->searchResults = array_values($resultsByDistance); return $this->searchResults; }
public function searchByProximity($center, $tolerance, $maxItems = 0) { $bbox = normalizedBoundingBox($center, $tolerance); $results = $this->filterPlacemarks($bbox); return $results; }