Package: pyatlas
PyAtlasA simplified Atlas API for PythonGetting StartedTo get setup in a new project folder, run:$ mkdir newproj && cd newproj
$ virtualenv venv --python=python3
$ source venv/bin/activateNOTE:pyatlaswill automatically install the dependencies it needs, including
the Protocol Buffers Python runtime -protobuf-2.6.1.
Therefore, it is highly recommended that you developpyatlasbased projects in
a Python virtual environment - you may need to installvirtualenvif you have not already.
(If you want to create apyatlasdistribution that does not automatically pull
in dependencies, see the next section.)Now that you have your virtual environment set up, you can installpyatlaswith:(venv) $ pip install pyatlasIf pip is unable to find thepyatlaspackage, you may need to build it from
source yourself. Check the next section for more info.To test that everything went smoothly, create a filehelloatlas.pywith the following code:frompyatlasimportpyatlas_globalfuncpyatlas_globalfunc.hello_atlas()Now run:(venv) $ python helloatlas.pyIf you see:Hello Atlas!then you're good to go!Building thepyatlasmoduleTo build thepyatlasmodule from source, run:$ git clone https://github.com/osmlab/atlas.git
$ cd atlas
$ ./gradlew cleanPyatlas buildPyatlasThis will generate a wheel file atpyatlas/dist. You can now install this withpiplike$ cd /path/to/project/that/uses/pyatlas
$ virtualenv venv --python=python2.7
$ source venv/bin/activate
$ pip install /path/to/atlas/pyatlas/dist/pyatlas-VERSION.whlAgain, it is recommended that you do this in the desired virtual environment.If you want to build apyatlaswheel file that does not automatically pull dependencies,
open upsetup.pyand remove the lines that sayinstall_requires=[
.
.
.
],Then re-run the./gradlew cleanPyatlas buildPyatlascommand from above and reinstall
usingpip. Note that you will now need to manage the required dependencies manually.Note on the formatterpyatlasuses theyapfformatting library to check for code format issues when building.
If you are running into issues after modifyingpyatlas, try running./gradlew applyFormatPyatlasNowpyatlasshould make it past theCHECKformat step!Note there is an issue that causes the formatter to goof if a source file does not
end with a newline (\n) character.
If theCHECKformat step is consistently failing after repeatedAPPLYsteps,
and you are seeing a message like the following:atlas.py: found issue, reformatting...with no formatter diff being displayed, check to make sure that the file has an ending newline.Documentationpyatlasdocumentation is automatically generated using thepydoctool and
stored in thedocfolder. To build
the documentation, run the gradle build command:$ ./gradlew cleanPyatlas buildPyatlasThis will generate HTML files detailing the functions and classes available in each module.Some sample use casespyatlasis a highly capable subset of the API provided by the JavaAtlas. Here are some examples
to get you started. Note that all of these examples were ran using thetest.atlasprovided in theresourcesfolder, and assume that you have an atlas variable defined like:frompyatlas.atlasimportAtlasatlas=Atlas('/path/to/atlas/pyatlas/resources/test.atlas')Getting features and metadataYou can get filtered iterables over anAtlas's features using the methods provided in theAtlasclass.# print all Nodesfornodeinatlas.nodes():printnode# print all Edges that have 'key1' as a tag keyforedgeinatlas.edges(predicate=lambdae:'key1'ine.get_tags().keys()):printedgeYou can also get a feature with a specific identifier like:# print the Relation with Atlas ID 2printatlas.relation(2)Metadata about theAtlasis also available. For a quick sample, try something like:metadata=atlas.metadata()printmetadata.number_of_pointsprintmetadata.countryCheck outdoc/atlas.htmlanddoc/atlas_metadata.htmlfor more information.Operating on featuresTheAtlasfeatures themselves support a set of operations defined in their respective classes.Here is a quick example:# print the tag dict for Point with Atlas ID 3printatlas.point(3).get_tags()# print all Relations of which the Node with Atlas ID 1 is a memberforrelationinatlas.node(1).relations():printrelation# print all the members of Relation with Atlas ID 1formemberinatlas.relation(1).get_members():# print the RelationMember objectprintmember# print the actual AtlasEntity contained in the RelationMemberprintmember.get_entity()Nodes andEdges, in particular, support traversal through their connectivity API.
Here are just the basics of what you can do with the connectivity interface:# print Edges connected to Node with ID 3foredgeinatlas.node(3).in_edges():printedgeforedgeinatlas.node(3).out_edges():printedgeforedgeinatlas.node(3).connected_edges():printedge# print the start and end Nodes of Edge 1printatlas.edge(1).start()printatlas.edge(1).end()Many more methods are provided. See the classes indoc/atlas_entities.htmlfor more information.Geometrypyatlasfeatures some really simple geometry primitives for working with locations and shapes on the
surface of the Earth. Here is a simple example that uses these primitives:frompyatlasimportgeometryfrompyatlas.geometryimportLocation,PolyLine,Polygon,Rectangle# Location constructor (lat/lon ordering) uses dm7 by default, see Location docs for info on dm7loc1=Location(385000000,-1160200000)# create the same Location but with degree values instead (lat/lon ordering)loc2=geometry.location_with_degrees(38.5,-116.02)printloc1.get_latitude_deg()printloc2.get_latitude()# create a new PolyLine with two shape pointspolyline1=PolyLine([Location(385000000,-1160200000),Location(395000000,-116300000)])forlocinpolyline1.locations():printlocprintpolyline1.bounds()# create a new Polygon with specified verticespolygon1=Polygon([geometry.location_with_degrees(0,0),geometry.location_with_degrees(10,0),geometry.location_with_degrees(5,10)])printpolygon1# print the vertices, will print the first again at the end to simulate closednessforlocinpolygon1.closed_loop():printlocprintpolygon1.bounds()# will print True, since the point lies inside the triangleprintpolygon1.fully_geometrically_encloses_location(geometry.location_with_degrees(5,5))# create a new Rectangle with given lower left and upper right cornersrect=Rectangle(geometry.location_with_degrees(0,0),geometry.location_with_degrees(20,20))printrect# this Rectangle intersects (overlaps at any point) polygon1printrect.intersects(polygon1)See the classes indoc/geometry.htmlfor more information.Spatial queriespyatlassupports some simple spatial queries over its feature space. The queries use the geometry
primitives provided by thegeometrymodule, but convert toShapelyprimitives under the hood to make queries into a nativelibgeos-backedR-tree.
Below are examples for a few of the spatial queries theAtlassupports:frompyatlasimportgeometryfrompyatlas.geometryimportRectangle# print all Points intersecting a given Polygon that also have "key1" as a tag keylower_left=geometry.location_with_degrees(37,-118.02)upper_right=geometry.location_with_degrees(39,-118)forpointinatlas.points_within(Rectangle(lower_left,upper_right),predicate=lambdae:'key1'ine.get_tags().keys()):printpoint# print all Relations with at least one member intersecting a given Polygonlower_left=geometry.location_with_degrees(37.999,-118.001)upper_right=geometry.location_with_degrees(38.001,-117.999)forrelationinatlas.relations_with_entities_intersecting(Rectangle(lower_left,upper_right)):printrelation# print all Edges that intersect a given Polygonlower_left=geometry.location_with_degrees(38,-120)upper_right=geometry.location_with_degrees(40,-117)foredgeinatlas.edges_intersecting(Rectangle(lower_left,upper_right)):printedgeSeedoc/atlas.htmlfor more information on the available spatial queries.