2 dsphere, GeoJSON, andDoctrineMongoDB

Source: Internet
Author: User
Tags derick
ByJeremyMikola, 10gensoftwareengineerandmaintainerofDoctrineMongoDBODM. ItseemsthatGeoJSONisalltheragethesedays. Lastmonth, region, one

By Jeremy Mikola, 10gen software engineer and maintainer of Doctrine MongoDB ODM. it seems that GeoJSON is all the rage these days. last month, Ian Bentley shared a bit about the new geospatial features in MongoDB 2.4. derick Rethans, one

By Jeremy Mikola, 10gen software engineer and maintainer of Doctrine MongoDB ODM.

It seems that GeoJSON is all the rage these days. last month, Ian Bentley shared a bit about the new geospatial features in MongoDB 2.4. derick Rethans, one of my PHP driver teammates and a renowned OpenStreetMap aficionado, recently blogged about importing OSM data into MongoDB as GeoJSON objects. A few days later, GitHub added support for rendering.geojsonFiles in repositories, using a combination of Leaflet. js, MapBox, and OpenStreetMap data. coincidentally, I visited a local CloudCamp meetup last week to present on geospatial data, and for the past two weeks I 've been working on adding support for MongoDB 2.4's geospatial query operators to Doctrine MongoDB.

Doctrine MongoDB is an alternative action for the PHP driver that provides a fluent query builder API among other useful features. it's used internally by Doctrine MongoDB ODM, but is completely usable on its own. one of the challenges in developing the library has been supporting multiple versions of MongoDBAndThe PHP driver. The introduction of read preferences last year is one such example. We wanted to still allow users to setslaveOkBits for older server and driver versions, but allow read preferences to apply for newer versions, all without breaking our API and abiding by semantic versioning. Now,setSlaveOkay()Method in Doctrine MongoDB will invokesetReadPreference()If it exists in the driver, and fall back to the deprecatedsetSlaveOkay()Driver method otherwise.

Query Builder API

Before ping into the geospatial changes for Doctrine MongoDB, let's take a quick look at the query builder API. Suppose we had a collection,test.places, With some OpenStreetMap annotations (key=valueStrings) stored intagsArray andlocField containing longpolling/latitude coordinates in MongoDB's legacy point format (a float tuple) for2dIndex. Doctrine's API allows queries to be constructed like so:

$connection = new \Doctrine\MongoDB\Connection();    $collection = $connection->selectCollection('test', 'places');    $qb = $collection->createQueryBuilder()        ->field('loc')            ->near(-73.987415, 40.757113)            ->maxDistance(0.00899928);        ->field('tags')            ->equals('amenity=restaurant');    $cursor = $qb->getQuery()->execute();

This above example executes the following query:

   {        "loc": {            "$near": [-73.987415, 40.757113],            "$maxDistance": 0.00899928        },        "tags": "amenity=restaurant"    }

This simple query will return your ants within half a kilometer of 10gen's NYC office at 229 West 43rd Street. If only it was so easy to findGoodYour Ants near Times Square!

Supporting New and Old Geospatial Queries

When the new2dsphereIndex type was introduced in MongoDB 2.4, operators such$nearAnd$geoWithinWere changed to accept GeoJSON geometry objects in addition to their legacy point and shape arguments.$nearWas particle ly problematic because of its optional$maxDistanceArgument. As shown abve,$maxDistancePreviusly sat alongside$nearAnd was measured in radians. It now sits$nearAnd is measured in meters. Using2dsphereIndex and GeoJSON points, the same query takes on a whole new shape:

   {        "loc": {            "$near": {                "$geometry": {                    "type": "Point",                    "coordinates" [-73.987415, 40.757113]                },                "$maxDistance": 500            }        },        "tags": "amenity=restaurant"    }

This posed a hurdle for Doctrine MongoDB's query builder, because we wanted to support2dsphereQueries without drastically changing the API. Unfortunately, there was no obvious waynear()To discern whether a pair of floats denoted a legacy or GeoJSON point, or whether a number signiied radians or meters in the casemaxDistance(). I also anticipated we might run into a similar quandry for$geoWithinBuilder method, which accepts an array of point coordinates.

Method overloading seemed preferable to creating separate builder methods or introducing a new "mode" parameter to handle2dsphereQueries. although PHP has no language-level support for overloading, it is commonly implemented by inspecting an argument's type at runtime. in our case, this wowould necessitate having classes for GeoJSON geometries (e.g. point, LineString, Polygon), which we cocould differentiate from the legacy geometry arrays.

Introducing a GeoJSON Library for PHP

A cursory search for GeoJSON PHP libraries turned up php-geojson, from the MapFish project, and geoPHP. I was pleased to see that geoPHP was available via Composer (PHP's de facto package manager), but neither library implemented the GeoJSON spec in its entirety. this seemed like a ripe opportunity to create such a library, and so geojson was born a few days later.

At the time of this writing,2dsphereSupport for Doctrine's query builder is still being developed; however, I envision it will take the following form when complete:

  use GeoJson\Geometry\Point;    // ...    $qb = $collection->createQueryBuilder()        ->field('loc')            ->near(new Point([-73.987415, 40.757113]))            ->maxDistance(0.00899928);        ->field('tags')            ->equals('amenity=restaurant');

All of the GeoJson classes implement JsonSerializable, one of the newer interfaces introduced in PHP 5.4, which will allow Doctrine to prepare them for MongoDB queries with a single method call. one clear benefit over the legacy geometry arrays is that the GeoJson library performs its own validation. when a Polygon is passedgeoWithin(), Doctrine won't have to worry about whether all of its rings are closed LineStrings; the library wocould catch such an error in the constructor. this helps achieve a separation of concerns, which in turn increases the maintainability of both libraries.

I look forward to finishing up2dsphereSupport for Doctrine MongoDB in the coming weeks. in the meantime, if you happen to fall in the fabled demographic of PHP developers in need of a full GeoJSON implementation, please give geojson a look and share some feedback.

Original article address: 2 dsphere, GeoJSON, and Doctrine MongoDB. Thank you for sharing it with me.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.