/** * Convert an array of WKT into a Geometry and features. * * @return array * An array containing the Geometry and the features. * @throws \exception */ private function initialDataToGeomFeatures() { geophp_load(); $initial_data = $this->getOption('initialData', ''); $geom = new \GeometryCollection(array()); $features = array(); // Process initial data. Ensure it's WKT. if (isset($initial_data)) { $geoms = array(); // Process strings and arrays likewise. if (!is_array($initial_data)) { $initial_data = array($initial_data); } foreach ($initial_data as $delta => $item) { if (is_array($item) && array_key_exists('geom', $item)) { $geoms[] = geoPHP::load($item['geom']); } } $geom = geoPHP::geometryReduce($geoms); // If we could parse the geom process further. if ($geom && !$geom->isEmpty()) { if (in_array($geom->getGeomType(), array('MultiPoint', 'MultiLineString', 'MultiPolygon', 'GeometryCollection'))) { foreach ($geom->getComponents() as $component) { $features[] = array('wkt' => $component->out('wkt'), 'projection' => 'EPSG:4326'); } } else { $features[] = array('wkt' => $geom->out('wkt'), 'projection' => 'EPSG:4326'); } } } return array('geom' => $geom, 'features' => $features); }
/** * {@inheritdoc} */ public function getJS() { // Ensure the options are properly set and clean. $this->setOption('dataType', array_filter($this->getOption('dataType', array('WKT' => 'WKT')))); $this->setOption('typeOfFeature', array_filter($this->getOption('typeOfFeature', array()))); $this->setOption('actionFeature', array_filter($this->getOption('actionFeature', array()))); $initial_data = $this->getOption('initialData'); // Process initial data. Ensure it's WKT. if (isset($initial_data)) { // Process strings and arrays likewise. geophp_load(); if (!is_array($initial_data)) { $initial_data = array($initial_data); } $geoms = array(); foreach ($initial_data as $delta => $item) { if (is_array($item) && array_key_exists('geom', $item)) { $geoms[] = geoPHP::load($item['geom']); } else { // Is this really necessary ? Commented for now. // $geoms[] = geoPHP::load(''); } } $combined_geom = geoPHP::geometryReduce($geoms); // If we could parse the geom process further. if ($combined_geom && !$combined_geom->isEmpty()) { // We want to force the combined_geom into a geometryCollection. $geom_type = $combined_geom->geometryType(); if ($geom_type == 'MultiPolygon' || $geom_type == 'MultiLineString' || $geom_type == 'MultiPoint') { $combined_geom = new \GeometryCollection($combined_geom->getComponents()); } // Ensure proper initial data in the textarea / hidden field. $data_type = key($this->getOption('dataType', array('WKT' => 'WKT'))); $this->setOption('initialData', $combined_geom->out(strtolower($data_type))); $this->setOption('initialDataType', $data_type); } else { // Set initial data to NULL if the data couldn't be evaluated. $this->setOption('initialData', NULL); $this->setOption('initialDataType', key($this->getOption('dataType', array('WKT' => 'WKT')))); } } return parent::getJS(); }
/** * Convert an object into a GeoPHP Geometry object. * * The following rules will dictate the conversion: * - Multi-value geofields of different types will be reduced to a * GEOMETRYCOLLECTION. * - Multi-value geofields of the same 'simple type' (POINT, LINESTRING or * POLYGON) will be reduced to the MULTI* equivalent. * - GEOMETRYCOLLECTION's containing multiple values of only one 'simple type' * will be reduced to the MULTI* equvalent. * - GEOMETRYCOLLECTION's or MULTI* values containing only one geometry will be * reduced to that geometery. * * @param Traversable $object * An object that represents a geometry or a (traversable) collection of * such objects. * * @param Callable $to_geom * A callback that takes your object and returns a GeoPHP Geometry object. * * @return * A GeoPHP Geometry object representing the $object value * converted according to the above rules. */ protected function createGeoPHPGeometry($object, $to_geom = NULL) { geophp_load(); if (empty($object)) { return NULL; } if (!$to_geom) { $to_geom = function ($wkt) { return \geoPHP::load($wkt, 'wkt'); }; } // TODO: This reflection sucks. if (is_array($object) || $object instanceof \Traversable && $object instanceof \Countable && $object instanceof \ArrayAccess) { foreach ($object as $delta => $value) { $geometry = $this->createGeoPHPGeometry($value, $to_geom); if ($geometry) { $geom[] = $geometry; } } } else { $geom = $to_geom($object); } return \geoPHP::geometryReduce($geom); }
/** * */ protected function geometry() { if (!$this->processed || $reset) { $this->process(); } geophp_load(); return \geoPHP::geometryReduce(array_map(function ($feature) { // TODO: GeoPHP cannot parse an array-based representation of a GeoJSON // object. We have to encode the array then parse the JSON string. $json = json_encode($feature->geometry); return \geoPHP::load($json, 'json'); }, $this->features)); }
/** * Compute the GeoJSON features array. * * @return array * The geojson array. */ protected function getGeojsonFeatures() { $features = array(); foreach ($this->getOption('fields', array()) as $field) { $feature = array('type' => 'Feature'); if (isset($field['title']) && !empty($field['title'])) { $feature['properties']['name'] = $field['title']; } if (isset($field['description']) && !empty($field['description'])) { $feature['properties']['description'] = $field['description']; } $json = FALSE; if (isset($field['wkt']) && !empty($field['wkt'])) { geophp_load(); $geophp = \geoPHP::load($field['wkt'], 'wkt'); if (is_object($geophp)) { $json = $geophp->out('json'); } } else { if (isset($field['address']) && !empty($field['address'])) { $geocoder = geocoder($this->getOption('geocoder_handler', 'google'), $field['address'], array(), $this->getOption('geocoder_cache', 2)); if (is_object($geocoder)) { $json = $geocoder->out('json'); } } } if ($json) { $feature['geometry'] = json_decode($json, TRUE); $features[] = $feature; } } return $features; }