/** * Converts an stdClass object into a Geometry based on its 'type' property * Converts an stdClass object into a Geometry, based on its 'type' property * * @param stdClass $obj Object resulting from json decoding a GeoJSON string * * @return object Object from class eometry */ private static function toInstance($obj) { if (is_null($obj)) { return null; } if (!isset($obj->type)) { self::checkType($obj); } if ($obj->type == 'Feature') { $instance = self::toGeomInstance($obj->geometry); } else { if ($obj->type == 'FeatureCollection') { $geometries = array(); foreach ($obj->features as $feature) { $geometries[] = self::toGeomInstance($feature->geometry); } // Get a geometryCollection or MultiGeometry out of the the provided geometries $instance = geoPHP::geometryReduce($geometries); } else { // It's a geometry $instance = self::toGeomInstance($obj); } } return $instance; }
protected function geomFromXML() { $geometries = array(); $geometries = array_merge($geometries, $this->parseWaypoints()); $geometries = array_merge($geometries, $this->parseTracks()); $geometries = array_merge($geometries, $this->parseRoutes()); if (empty($geometries)) { throw new Exception("Invalid / Empty GPX"); } return geoPHP::geometryReduce($geometries); }
function testPlaceholders() { foreach (scandir('./input') as $file) { $parts = explode('.', $file); if ($parts[0]) { $format = $parts[1]; $value = file_get_contents('./input/' . $file); $geometry = geoPHP::load($value, $format); $placeholders = array(array('name' => 'hasZ'), array('name' => 'is3D'), array('name' => 'isMeasured'), array('name' => 'isEmpty'), array('name' => 'coordinateDimension'), array('name' => 'z'), array('name' => 'm')); foreach ($placeholders as $method) { $argument = NULL; $method_name = $method['name']; if (isset($method['argument'])) { $argument = $method['argument']; } switch ($method_name) { case 'm': case 'z': if ($geometry->geometryType() == 'Point') { $this->assertNotNull($geometry->{$method_name}($argument), 'Failed on ' . $method_name); } if ($geometry->geometryType() == 'LineString') { $this->assertNotNull($geometry->{$method_name}($argument), 'Failed on ' . $method_name); } if ($geometry->geometryType() == 'MultiLineString') { $this->assertNull($geometry->{$method_name}($argument), 'Failed on ' . $method_name); } break; case 'coordinateDimension': case 'isEmpty': case 'isMeasured': case 'is3D': case 'hasZ': if ($geometry->geometryType() == 'Point') { $this->assertNotNull($geometry->{$method_name}($argument), 'Failed on ' . $method_name); } if ($geometry->geometryType() == 'LineString') { $this->assertNotNull($geometry->{$method_name}($argument), 'Failed on ' . $method_name); } if ($geometry->geometryType() == 'MultiLineString') { $this->assertNotNull($geometry->{$method_name}($argument), 'Failed on ' . $method_name); } break; default: $this->assertTrue($geometry->{$method_name}($argument), 'Failed on ' . $method_name); } } } } }
/** * Given an object or a string, return a Geometry * * @param mixed $input The GeoJSON string or object * * @return object Geometry */ public function read($input) { if (is_string($input)) { $input = json_decode($input); } if (!is_object($input)) { throw new Exception('Invalid JSON'); } if (!is_string($input->type)) { throw new Exception('Invalid JSON'); } // Check to see if it's a FeatureCollection if ($input->type == 'FeatureCollection') { $geoms = array(); foreach ($input->features as $feature) { $geoms[] = $this->read($feature); } return geoPHP::geometryReduce($geoms); } // Check to see if it's a Feature if ($input->type == 'Feature') { return $this->read($input->geometry); } // It's a geometry - process it return $this->objToGeom($input); }
public function sql2json($SQL, $shape_column, $popup_content = NULL, $label = NULL) { require_once APPPATH . '../modules/' . $this->cms_module_path('gofrendi.gis.core') . '/classes/geoPHP/geoPHP.inc'; $map_region = $this->input->post('map_region'); $map_zoom = $this->input->post('map_zoom'); $search = array('@map_region', '@map_zoom'); $replace = array($map_region, $map_zoom); $SQL = $this->replace($SQL, $search, $replace); $features = array(); $query = $this->db->query($SQL); foreach ($query->result_array() as $row) { $geom = geoPHP::load($row[$shape_column], 'wkt'); $json = $geom->out('json'); $real_popup_content = ""; $real_label = ""; $search = array(); $replace = array(); foreach ($row as $column => $value) { $search[] = '@' . $column; $replace[] = $value; } if (isset($popup_content)) { $real_popup_content = $this->replace($popup_content, $search, $replace); } if (isset($label)) { $real_label = $this->replace($label, $search, $replace); } $features[] = array("type" => "Feature", "properties" => array("popupContent" => $real_popup_content, "label" => $real_label), "geometry" => json_decode($json)); } $feature_collection = array("type" => "FeatureCollection", "features" => $features); return json_encode($feature_collection); }
public function centroid() { if ($this->isEmpty()) { return NULL; } if ($this->geos()) { return geoPHP::geosToGeometry($this->geos()->centroid()); } $exterior_ring = $this->components[0]; $pts = $exterior_ring->getComponents(); $c = count($pts); if ((int) $c == '0') { return NULL; } $cn = array('x' => '0', 'y' => '0'); $a = $this->area(TRUE, TRUE); // If this is a polygon with no area. Just return the first point. if ($a == 0) { return $this->exteriorRing()->pointN(1); } foreach ($pts as $k => $p) { $j = ($k + 1) % $c; $P = $p->getX() * $pts[$j]->getY() - $p->getY() * $pts[$j]->getX(); $cn['x'] = $cn['x'] + ($p->getX() + $pts[$j]->getX()) * $P; $cn['y'] = $cn['y'] + ($p->getY() + $pts[$j]->getY()) * $P; } $cn['x'] = $cn['x'] / (6 * $a); $cn['y'] = $cn['y'] / (6 * $a); $centroid = new Point($cn['x'], $cn['y']); return $centroid; }
function wkb_to_json($wkb) { $geom = geoPHP::load($wkb, 'wkb'); // echo $geom->out('json'); // exit(); return $geom->out('json'); }
/** * Convert a raw coverage value to WKT. * * @param string $coverage The raw coverage. * @return string|null The WKT. */ function nl_extractWkt($coverage) { $wkt = null; // Get coverage format. $format = geoPHP::detectFormat($coverage); // Convert / reduce to WKT. if (in_array($format, array('wkt', 'kml'))) { $wkt = geoPHP::load($coverage)->out('wkt'); } return $wkt; }
/** * Implements hook_tourml_asset() * * @param $asset. * * @return $asset. An altered asset object * * Use this hook to render assets. The geofield * module stores its data in $asset['wkt'] so * we can check against this value to determine * that we have a geofield, and act upon it. */ function tap_geo_tourml_asset($asset) { // Handle geofield fields if (isset($asset['wkt'])) { geofield_load_geophp(); $geometry = geoPHP::load($asset['wkt'], 'wkt'); if ($geometry) { $asset['value'] = $geometry->out('json'); } } return $asset; }
protected function testInsertGeometry(Connection $connection) { $i = 0; $connection->beginTransaction(); $collection = \geoPHP::load(file_get_contents(self::$kml), 'kml'); $collection->setSRID(4326); $connection->insert('test_table', array('id' => $i++, 'name' => 'test_' . $i, 'geometry' => $collection), array('integer', 'string', 'geometry')); $connection->commit(); $data = $connection->fetchAll('SELECT * FROM test_table'); $this->assertEquals(1, count($data)); $this->assertEquals(0, $data[0]['id']); $this->assertEquals('test_1', $data[0]['name']); }
/** * Serialize geometries into a WKT string. * * @param Geometry $geometry * * @return string The WKT string representation of the input geometries */ public function write(Geometry $geometry) { // If geos is installed, then we take a shortcut and let it write the WKT if (geoPHP::geosInstalled()) { $writer = new GEOSWKTWriter(); return $writer->write($geometry->geos()); } $type = strtolower($geometry->geometryType()); if (is_null($data = $this->extract($geometry))) { return null; } return strtoupper($type) . ' (' . $data . ')'; }
protected function geomFromXML() { $geometries = array(); $geometries = array_merge($geometries, $this->parsePoints()); $geometries = array_merge($geometries, $this->parseLines()); $geometries = array_merge($geometries, $this->parsePolygons()); $geometries = array_merge($geometries, $this->parseBoxes()); $geometries = array_merge($geometries, $this->parseCircles()); if (empty($geometries)) { throw new Exception("Invalid / Empty GeoRSS"); } return geoPHP::geometryReduce($geometries); }
function testAdapters() { foreach (scandir('./input', SCANDIR_SORT_NONE) as $file) { $parts = explode('.', $file); if ($parts[0]) { $format = $parts[1]; $input = file_get_contents('./input/' . $file); echo "\nloading: " . $file . " for format: " . $format; $geometry = geoPHP::load($input, $format); // Test adapter output and input. Do a round-trip and re-test foreach (geoPHP::getAdapterMap() as $adapter_key => $adapter_class) { if ($adapter_key != 'google_geocode') { //Don't test google geocoder regularily. Uncomment to test $output = $geometry->out($adapter_key); $this->assertNotNull($output, "Empty output on " . $adapter_key); if ($output) { $adapter_loader = new $adapter_class(); $test_geom_1 = $adapter_loader->read($output); $test_geom_2 = $adapter_loader->read($test_geom_1->out($adapter_key)); $this->assertEquals($test_geom_1->out('wkt'), $test_geom_2->out('wkt'), "Mismatched adapter output in " . $adapter_class . ' (test file: ' . $file . ')'); } } } // Test to make sure adapter work the same wether GEOS is ON or OFF // Cannot test methods if GEOS is not intstalled if (!geoPHP::geosInstalled()) { return; } foreach (geoPHP::getAdapterMap() as $adapter_key => $adapter_class) { if ($adapter_key != 'google_geocode') { //Don't test google geocoder regularily. Uncomment to test // Turn GEOS on geoPHP::geosInstalled(TRUE); $output = $geometry->out($adapter_key); if ($output) { $adapter_loader = new $adapter_class(); $test_geom_1 = $adapter_loader->read($output); // Turn GEOS off geoPHP::geosInstalled(FALSE); $test_geom_2 = $adapter_loader->read($output); // Turn GEOS back On geoPHP::geosInstalled(TRUE); // Check to make sure a both are the same with geos and without $this->assertEquals($test_geom_1->out('wkt'), $test_geom_2->out('wkt'), "Mismatched adapter output between GEOS and NORM in " . $adapter_class . ' (test file: ' . $file . ')'); } } } } } }
function testGeos() { if (!geoPHP::geosInstalled()) { echo "Skipping GEOS -- not installed"; return; } foreach (scandir('./input') as $file) { $parts = explode('.', $file); if ($parts[0]) { $format = $parts[1]; $value = file_get_contents('./input/' . $file); echo "\nloading: " . $file . " for format: " . $format; $geometry = geoPHP::load($value, $format); $geosMethods = array(array('name' => 'geos'), array('name' => 'setGeos', 'argument' => $geometry->geos()), array('name' => 'PointOnSurface'), array('name' => 'equals', 'argument' => $geometry), array('name' => 'equalsExact', 'argument' => $geometry), array('name' => 'relate', 'argument' => $geometry), array('name' => 'checkValidity'), array('name' => 'isSimple'), array('name' => 'buffer', 'argument' => '10'), array('name' => 'intersection', 'argument' => $geometry), array('name' => 'convexHull'), array('name' => 'difference', 'argument' => $geometry), array('name' => 'symDifference', 'argument' => $geometry), array('name' => 'union', 'argument' => $geometry), array('name' => 'simplify', 'argument' => '0'), array('name' => 'disjoint', 'argument' => $geometry), array('name' => 'touches', 'argument' => $geometry), array('name' => 'intersects', 'argument' => $geometry), array('name' => 'crosses', 'argument' => $geometry), array('name' => 'within', 'argument' => $geometry), array('name' => 'contains', 'argument' => $geometry), array('name' => 'overlaps', 'argument' => $geometry), array('name' => 'covers', 'argument' => $geometry), array('name' => 'coveredBy', 'argument' => $geometry), array('name' => 'distance', 'argument' => $geometry), array('name' => 'hausdorffDistance', 'argument' => $geometry)); foreach ($geosMethods as $method) { $argument = NULL; $method_name = $method['name']; if (isset($method['argument'])) { $argument = $method['argument']; } switch ($method_name) { case 'isSimple': case 'equals': case 'geos': if ($geometry->geometryType() == 'Point') { $this->assertNotNull($geometry->{$method_name}($argument), 'Failed on ' . $method_name . ' (test file: ' . $file . ')'); } if ($geometry->geometryType() == 'LineString') { $this->assertNotNull($geometry->{$method_name}($argument), 'Failed on ' . $method_name . ' (test file: ' . $file . ')'); } if ($geometry->geometryType() == 'MultiLineString') { $this->assertNotNull($geometry->{$method_name}($argument), 'Failed on ' . $method_name . ' (test file: ' . $file . ')'); } break; default: if ($geometry->geometryType() == 'Point') { $this->assertNotNull($geometry->{$method_name}($argument), 'Failed on ' . $method_name . ' (test file: ' . $file . ')'); } if ($geometry->geometryType() == 'LineString') { $this->assertNotNull($geometry->{$method_name}($argument), 'Failed on ' . $method_name . ' (test file: ' . $file . ')'); } if ($geometry->geometryType() == 'MultiLineString') { $this->assertNull($geometry->{$method_name}($argument), 'Failed on ' . $method_name . ' (test file: ' . $file . ')'); } } } } } }
function get_bbox($gpx_str) { require_once "geoPHP/geoPHP.inc"; $geom = geoPHP::load($gpx_str, 'gpx'); $bbox = $geom->getBBox(); $tl = $this->is_taiwan($bbox['minx'], $bbox['maxy']); $br = $this->is_taiwan($bbox['maxx'], $bbox['miny']); if ($tl != $br) { $this->taiwan = 0; } $this->taiwan = $tl; // 0 or 1 or 2 //echo "lon $minlon $maxlon, lat $maxlat $minlat\n"; exit; return array($bbox['minx'], $bbox['maxy'], $bbox['maxx'], $bbox['miny']); }
function testMethods() { $format = 'gpx'; $value = file_get_contents('./input/20120702.gpx'); $geometry = geoPHP::load($value, $format); $methods = array(array('name' => 'area'), array('name' => 'boundary'), array('name' => 'getBBox'), array('name' => 'centroid'), array('name' => 'length'), array('name' => 'greatCircleLength', 'argument' => 6378137), array('name' => 'haversineLength'), array('name' => 'y'), array('name' => 'x'), array('name' => 'numGeometries'), array('name' => 'geometryN', 'argument' => '1'), array('name' => 'startPoint'), array('name' => 'endPoint'), array('name' => 'isRing'), array('name' => 'isClosed'), array('name' => 'numPoints'), array('name' => 'pointN', 'argument' => '1'), array('name' => 'exteriorRing'), array('name' => 'numInteriorRings'), array('name' => 'interiorRingN', 'argument' => '1'), array('name' => 'dimension'), array('name' => 'geometryType'), array('name' => 'SRID'), array('name' => 'setSRID', 'argument' => '4326')); foreach ($methods as $method) { $argument = NULL; $method_name = $method['name']; if (isset($method['argument'])) { $argument = $method['argument']; } $this->_methods_tester($geometry, $method_name, $argument); } }
/** * */ public function within(Request $request) { $start = microtime(true); if (str_contains($request->path(), 'mongo')) { $collection = $this->model->within($request->json('geometry.coordinates')); $elapsed = microtime(true) - $start; } else { $geometry = \geoPHP::load($request->input('geometry'), 'wkt'); $collection = $this->model->within($geometry->asText('wkt')); $elapsed = microtime(true) - $start; } $logMessage = 'ms to get %s data: %f in %s'; \Log::debug(sprintf($logMessage, str_contains($request->path(), 'mongo') ? 'Mongo' : 'PostGIS', $elapsed, 'within()')); return Response::json(['points' => $collection, 'area' => 0]); }
public static function getBody($dataObj) { // Check if the original data is not GeoJSON if (!empty($dataObj->geo_formatted) && $dataObj->geo_formatted) { if ($dataObj->source_definition['type'] == 'JSON') { return json_encode($dataObj->data); } elseif ($dataObj->source_definition['type'] == 'KML') { $geom = \geoPHP::load($dataObj->data, 'kml'); return $geom->out('json'); } } // Build the body $body = $dataObj->data; if (is_object($body)) { $body = get_object_vars($dataObj->data); } $features = array(); foreach ($body as $dataRow) { if (is_object($dataRow)) { $dataRow = get_object_vars($dataRow); } $geo = $dataObj->geo; //Guess lat/lon if no geo information was given for this if (empty($geo)) { if ($lat_long = GeoHelper::findLatLong($dataRow)) { $geo = array("latitude" => $lat_long[0], "longitude" => $lat_long[1]); } } $geometric_ids = self::findGeometry($geo, $dataRow); //Prevent geo information being duplicated in properties foreach ($geometric_ids[0] as $geometric_id) { unset($dataRow[$geometric_id]); } $feature = array('type' => 'Feature', 'geometry' => $geometric_ids[1], 'properties' => $dataRow); $id_prop = @$dataObj->source_definition['map_property']; if (!empty($id_prop) && !empty($dataRow[$id_prop])) { $feature['id'] = $dataRow[$id_prop]; unset($dataRow[$id_prop]); } array_push($features, $feature); } $result = array('type' => 'FeatureCollection', 'features' => $features); // Only add bounding box if we have features and are viewing the entire dataset. if (!empty($features) && empty($dataObj->paging)) { $result['bbox'] = self::boundingBox($features); } return json_encode($result); }
/** * Return record coverage data from the NeatlineFeatures plugin. * * @param $record NeatlineRecord The record to get the feature for. * @return string|null */ function nl_getNeatlineFeaturesWkt($record) { // Halt if Features is not present. if (!plugin_is_active('NeatlineFeatures')) { return; } $db = get_db(); // Get raw coverage. $result = $db->fetchOne("SELECT geo FROM `{$db->prefix}neatline_features`\n WHERE is_map=1 AND item_id=?;", $record->item_id); if ($result) { // If KML, convert to WKT. if (geoPHP::detectFormat($result) == 'kml') { $result = nl_kml2wkt(trim($result)); } else { $result = 'GEOMETRYCOLLECTION(' . implode(',', explode('|', $result)) . ')'; } } return $result; }
function test_postgis($name, $type, $geom, $connection, $format) { global $table; // Let's insert into the database using GeomFromWKB $insert_string = pg_escape_bytea($geom->out($format)); pg_query($connection, "INSERT INTO {$table} (name, type, geom) values ('{$name}', '{$type}', GeomFromWKB('{$insert_string}'))"); // SELECT using asBinary PostGIS $result = pg_fetch_all(pg_query($connection, "SELECT asBinary(geom) as geom FROM {$table} WHERE name='{$name}'")); foreach ($result as $item) { $wkb = pg_unescape_bytea($item['geom']); // Make sure to unescape the hex blob $geom = geoPHP::load($wkb, $format); // We now a full geoPHP Geometry object } // SELECT and INSERT directly, with no wrapping functions $result = pg_fetch_all(pg_query($connection, "SELECT geom as geom FROM {$table} WHERE name='{$name}'")); foreach ($result as $item) { $wkb = pack('H*', $item['geom']); // Unpacking the hex blob $geom = geoPHP::load($wkb, $format); // We now have a geoPHP Geometry // Let's re-insert directly into postGIS // We need to unpack the WKB $unpacked = unpack('H*', $geom->out($format)); $insert_string = $unpacked[1]; pg_query($connection, "INSERT INTO {$table} (name, type, geom) values ('{$name}', '{$type}', '{$insert_string}')"); } // SELECT and INSERT using as EWKT (ST_GeomFromEWKT and ST_AsEWKT) $result = pg_fetch_all(pg_query($connection, "SELECT ST_AsEWKT(geom) as geom FROM {$table} WHERE name='{$name}'")); foreach ($result as $item) { $wkt = $item['geom']; // Make sure to unescape the hex blob $geom = geoPHP::load($wkt, 'ewkt'); // We now a full geoPHP Geometry object // Let's re-insert directly into postGIS $insert_string = $geom->out('ewkt'); pg_query($connection, "INSERT INTO {$table} (name, type, geom) values ('{$name}', '{$type}', ST_GeomFromEWKT('{$insert_string}'))"); } }
/** * 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); }
public function kml($args) { $db = new Database($this->wpdb); $table = $db->get_table($args['table']); // Check that a point column exists. $points = $table->get_columns('point'); if (empty($points)) { // @TODO Show error. return; } $point_col = array_shift($points); $point_col_name = $point_col->get_name(); // Apply filters. $filter_param = isset($args['filter']) ? $args['filter'] : array(); $table->add_filters($filter_param); $table->add_filter($point_col_name, 'not empty', ''); // Create KML. $kml = new \SimpleXMLElement('<kml />'); $kml->addAttribute('xmlns', 'http://www.opengis.net/kml/2.2'); $kml_doc = $kml->addChild('Document'); foreach ($table->get_records(false) as $record) { $placemark = $kml_doc->addChild('Placemark'); $placemark->addChild('name', $record->get_title()); $placemark->addChild('description', htmlentities('<a href="' . $record->get_url() . '">View record.</a>')); $point = $placemark->addChild('Point'); $geom = \geoPHP::load($record->{$point_col_name}()); $point->addChild('coordinates', $geom->getX() . ',' . $geom->getY()); } // Send to browser. $download_name = date('Y-m-d') . '_' . $table->get_name() . '.kml'; header('Content-Encoding: UTF-8'); header('Content-type: application/vnd.google-earth.kml+xml; charset=UTF-8'); header('Content-Disposition: attachment; filename="' . $download_name . '"'); echo $kml->asXML(); exit; }
function processtweets($capturebucket) { global $tweetQueue; $querybins = getActiveBins(); // cache bin types $bintypes = array(); foreach ($querybins as $binname => $queries) { $bintypes[$binname] = getBinType($binname); } // running through every single tweet foreach ($capturebucket as $data) { if (!array_key_exists('entities', $data)) { // unexpected/irregular tweet data if (array_key_exists('delete', $data)) { // a tweet has been deleted. @todo: process continue; } // this can get very verbose when repeated? logit(CAPTURE . ".error.log", "irregular tweet data received."); continue; } // we run through every bin to check whether the received tweets fit foreach ($querybins as $binname => $queries) { $geobin = isset($bintypes[$binname]) && $bintypes[$binname] == 'geotrack'; if ($geobin && (!array_key_exists('geo_enabled', $data['user']) || $data['user']['geo_enabled'] !== true)) { // in geobins, process only geo tweets continue; } $found = false; if (CAPTURE == "track") { // we check for every query in the bin if they fit foreach ($queries as $query => $track) { if ($geobin) { $boxes = getGeoBoxes($track); // look for geolocation matches /* * Some notes on geolocation tracking * * Geolocation tracking is done inside the capture role: track * Geolocation query bins have a special type: geotrack * Geolocation phrases have a specific format: * = these phrases are a chain of geoboxes defined as 4 comma separated values (sw long, sw lat, ne long, ne lat) * = multiple world areas can thus be defined per bin * * Fetching (from Twitter) * * 1) Twitter will give us all the tweets which have excplicit GPS coordinates inside one of our queried areas. * 2) Additionaly Twitter give us those tweets with a user 'place' definition. A place (i.e. Paris) is itself a (set of) gps polygons * Twitter returns the tweets if one of these place polygons covers the same area as our geo boxes. * * And matching (by us) * * 1) These tweets will be put in the bin if the coordinate pair (longitude, latitude) fits in any one of the defined geoboxes in the bin. * 2) These tweets will be put in the bin if the geobox is _not_ completely subsumed by the place (example: the place is France and the geobox is Paris), but the geobox does overlap the place polygon or the geobox subsumes the place polygon. * */ if ($data["geo"] != null) { $tweet_lat = $data["geo"]["coordinates"][0]; $tweet_lng = $data["geo"]["coordinates"][1]; // does the tweet geo data fit in on of the boxes? foreach ($boxes as $box) { if (coordinatesInsideBoundingBox($tweet_lng, $tweet_lat, $box['sw_lng'], $box['sw_lat'], $box['ne_lng'], $box['ne_lat'])) { // logit(CAPTURE . ".error.log", "(debug) tweet with lng $tweet_lng and lat $tweet_lat versus (sw: " . $box['sw_lng'] . "," . $box['sw_lat'] . " ne: " . $box['ne_lng'] . "," . $box['ne_lat'] . ") matched to be inside the area"); $found = true; break; } else { // logit(CAPTURE . ".error.log", "(debug) tweet with lng $tweet_lng and lat $tweet_lat versus (sw: " . $box['sw_lng'] . "," . $box['sw_lat'] . " ne: " . $box['ne_lng'] . "," . $box['ne_lat'] . ") falls outside the area"); } } } else { // this is a gps tracking query, but the tweet has no gps geo data // Twitter may have matched this tweet based on the user-defined location data if (array_key_exists('place', $data) && is_array($data['place']) && array_key_exists('bounding_box', $data['place'])) { // Make a geoPHP object of the polygon(s) defining the place, by using a WKT (well-known text) string $wkt = 'POLYGON('; $polfirst = true; foreach ($data['place']['bounding_box']['coordinates'] as $p => $pol) { if ($polfirst) { $polfirst = false; } else { $wkt .= ', '; } $wkt .= '('; $first = true; $first_lng = 0; $first_lat = 0; foreach ($data['place']['bounding_box']['coordinates'][$p] as $i => $coords) { $point_lng = $coords[0]; $point_lat = $coords[1]; if ($first) { $first = false; $first_lng = $point_lng; $first_lat = $point_lat; } else { $wkt .= ', '; } $wkt .= $point_lng . ' ' . $point_lat; } // end where we started $wkt .= ', ' . $first_lng . ' ' . $first_lat; $wkt .= ')'; } $wkt .= ')'; $place = geoPHP::load($wkt, 'wkt'); // iterate over geoboxes in our track // place should not spatially contain our box, but it should overlap with it foreach ($boxes as $box) { // 'POLYGON((x1 y1, x1 y2, x2 y2, x2 y1, x1 y1))' $boxwkt = 'POLYGON((' . $box['sw_lng'] . ' ' . $box['sw_lat'] . ', ' . $box['sw_lng'] . ' ' . $box['ne_lat'] . ', ' . $box['ne_lng'] . ' ' . $box['ne_lat'] . ', ' . $box['ne_lng'] . ' ' . $box['sw_lat'] . ', ' . $box['sw_lng'] . ' ' . $box['sw_lat'] . '))'; $versus = geoPHP::load($boxwkt, 'wkt'); $contains = $place->contains($versus); $boxcontains = $versus->contains($place); $overlaps = $place->overlaps($versus); if (!$contains && ($boxcontains || $overlaps)) { // logit(CAPTURE . ".error.log", "place polygon $wkt allies with geobox $boxwkt"); $found = true; break; } } } } if ($found) { break; } } else { // look for keyword matches $pass = false; // check for queries with more than one word, but go around quoted queries if (preg_match("/ /", $query) && !preg_match("/'/", $query)) { $tmplist = explode(" ", $query); $all = true; foreach ($tmplist as $tmp) { if (!preg_match("/" . $tmp . "/i", $data["text"])) { $all = false; break; } } // only if all words are found if ($all == true) { $pass = true; } } else { // treat quoted queries as single words $query = preg_replace("/'/", "", $query); if (preg_match("/" . $query . "/i", $data["text"])) { $pass = true; } } // at the first fitting query, we break if ($pass == true) { $found = true; break; } } } } elseif (CAPTURE == "follow") { // we check for every query in the bin if they fit $found = in_array($data["user"]["id"], $queries) ? TRUE : FALSE; } elseif (CAPTURE == "onepercent") { // always match in onepercent $found = true; } // if the tweet does not fit in the current bin, go to the next tweet if ($found == false) { continue; } $tweet = new Tweet(); $tweet->fromJSON($data); $tweetQueue->push($tweet, $binname); } } $tweetQueue->insertDB(); return TRUE; }
/** * If a KML document is passed, it should be converted to WKT. */ public function testConvertKml() { $this->assertEquals(geoPHP::load('POINT(1 2)')->out('wkt'), nl_getWkt(self::KML)); }
function json_to_wkt($json) { $geom = geoPHP::load($json, 'json'); return $geom->out('wkt'); }
/** * Serialize geometries into a WKT string. * * @param Geometry $geometry * * @return string The WKT string representation of the input geometries */ public function write(Geometry $geometry) { // If geos is installed, then we take a shortcut and let it write the WKT if (geoPHP::geosInstalled()) { $writer = new GEOSWKTWriter(); $writer->setTrim(TRUE); return $writer->write($geometry->geos()); } if ($geometry->isEmpty()) { return strtoupper($geometry->geometryType()) . ' EMPTY'; } else { if ($data = $this->extractData($geometry)) { return strtoupper($geometry->geometryType()) . ' (' . $data . ')'; } } }
/** * */ 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)); }
<?php include_once "geophp/geoPHP.inc"; include_once "connection.php"; // CHANGE MySQL TO JSON : $SQL = "SELECT cat, nam as name, astext(shape) as shape FROM rivers"; $result = mysql_query($SQL, $connection); $features = array(); while ($row = mysql_fetch_array($result)) { $geom = geoPHP::load($row["shape"], 'wkt'); $json = $geom->out('json'); $features[] = array("type" => "Feature", "properties" => array("cat" => $row["cat"], "name" => $row["name"], "style" => array("color" => "#004070", "weight" => 1, "opacity" => 0.9), "popupContent" => $row["name"]), "geometry" => json_decode($json)); } $feature_collection = array("type" => "FeatureCollection", "features" => $features); echo json_encode($feature_collection, true);
function processDatamap_postProcessFieldArray($status, $table, $id, &$fieldArray, $obj) { switch ($table) { case 'fe_users': case 'tt_address': $config = tx_odsosm_div::getConfig(array('autocomplete')); // Search coordinates if ($config['autocomplete'] && ($fieldArray['zip'] || $fieldArray['city'] || $fieldArray['address'])) { $address = $obj->datamap[$table][$id]; if ($config['autocomplete'] == 2 || floatval($address['tx_odsosm_lon']) == 0) { $ll = tx_odsosm_div::updateAddress($address); if ($ll) { $fieldArray['tx_odsosm_lon'] = sprintf('%01.6f', $address['lon']); $fieldArray['tx_odsosm_lat'] = sprintf('%01.6f', $address['lat']); if ($address['street']) { $fieldArray['address'] = $address['street']; if ($address['housenumber']) { $fieldArray['address'] .= ' ' . $address['housenumber']; } } if ($address['zip']) { $fieldArray['zip'] = $address['zip']; } if ($address['city']) { $fieldArray['city'] = $address['city']; } if ($address['state'] && $table == 'tt_address') { $fieldArray['region'] = $address['state']; } if ($address['country']) { $fieldArray['country'] = $address['country']; } } } } break; case 'tx_odsosm_track': $filename = PATH_site . 'uploads/tx_odsosm/' . $fieldArray['file']; if ($fieldArray['file'] && file_exists($filename)) { require_once t3lib_extMgm::extPath('ods_osm', 'res/geoPHP/geoPHP.inc'); $polygon = geoPHP::load(file_get_contents($filename), pathinfo($filename, PATHINFO_EXTENSION)); $box = $polygon->getBBox(); $fieldArray['min_lon'] = sprintf('%01.6f', $box['minx']); $fieldArray['min_lat'] = sprintf('%01.6f', $box['miny']); $fieldArray['max_lon'] = sprintf('%01.6f', $box['maxx']); $fieldArray['max_lat'] = sprintf('%01.6f', $box['maxy']); } break; case 'tx_odsosm_marker': if ($fieldArray['icon'] && file_exists(PATH_site . 'uploads/tx_odsosm/' . $fieldArray['icon'])) { $size = getimagesize(PATH_site . 'uploads/tx_odsosm/' . $fieldArray['icon']); $fieldArray['size_x'] = $size[0]; $fieldArray['size_y'] = $size[1]; $fieldArray['offset_x'] = -round($size[0] / 2); $fieldArray['offset_y'] = -$size[1]; } break; case 'tx_odsosm_vector': if ($fieldArray['data']) { $this->lon = array(); $this->lat = array(); $vector = json_decode($fieldArray['data']); foreach ($vector->geometry->coordinates[0] as $coordinates) { $this->lon[] = $coordinates[0]; $this->lat[] = $coordinates[1]; } } $fieldArray['min_lon'] = sprintf('%01.6f', min($this->lon)); $fieldArray['min_lat'] = sprintf('%01.6f', min($this->lat)); $fieldArray['max_lon'] = sprintf('%01.6f', max($this->lon)); $fieldArray['max_lat'] = sprintf('%01.6f', max($this->lat)); break; } }
public function geometryToPHPValue($value = null) { return $value === null ? null : \geoPHP::load(pack('H*', $value), 'ewkb'); }