Let's parse, analyse and visualise spatial data in Pharo!
TABLE OF CONTENTS
Parse a GeoJSON
Example GeoJSON files are provided in GeoJSONExamples class, in "geojson examples" protocol.
You can parse your GeoJSON file as a string, and obtain generated object model, using "GeoJSONReader class >> fromString:".
GeoJSONReader fromString:(GeoJSONExamples barsLilleGJ).
You can parse your GeoJSON file giving an URL as parameter, using "GeoJSONReader class >> #fromURL:".
GeoJSONReader fromURL: 'https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/departements/59-nord/departement-59-nord.geojson'.
Inspect object model
Once you obtain your OGCObject (a FeatureCollection, a Feature or a Geometry), you can inspect and visualise it at the same time.
The OGCObject inspector contains 2 added tabs: "Map" & "Map with Tiles".
"Map" inspector tab renders a visualisation of geometries.
"Map with Tiles" inspector tab renders a visualisation on a map background.
Both tabs compute the most suitable zoom level to be displayed in a space of 3x2 tiles = 768x512 px.
You can also visualise your model in an independant way with: "OGCViewerMorph>>#displayObject:". You can combine it with "OGCViewerMorph class>>#withMapTiles:" to custom your display settings.
Display feature information
If you click on a feature on a visualisation, a window appears with :
the detail of associate properties
a button to inspect clicked feature
[TO DO] Zoom + move map
You can call analysis methods like intersection, inclusion, length, etc, ... detailed in Simple Feature Access specifications.
More information about spatial reference system's operations in OGC-Pharo model page.
We consider that geometries are located in the same plane.
Spatial reference system package to use: OGC-Geometry
Spatial reference system class to use: OGCGeometricProjection
We consider that geometries are located on Earth as a perfect sphere with ray of 6372.795477598 km.
Spatial reference system package to use: OGC-Spheric
Spatial reference system class to use: OGCSphericSystem
There are several ways to custom geospatial objects appearance.
For now, you can edit:
filling color with fill
fill opacity with fill-opacity
stroke color with stroke
stroke width with stroke-width
Default style is set in the "style" protocol of OGCGeometry class:
default filling color: white for Polygons
default fill opacity: 0.5 for Polygons
default stroke color: red
default stroke width: 2
Apply a global style with GeoJSON integration
A custom style can be directly found in GeoJSON file, in the 'geometry' dictionary of a feature, alongside type and coordinates. Style must be a dictionary of strings using following keys: "fill", "fill-opacity", "stroke" and "stroke-width".
"GeoJSONExamples class >> #aMultiPolygonGJ" is a great example of style integration to GeoJSON.
Apply a global style with a method
You can obtain the same result using "OGCObject >> #applyStyle:" method. This method takes a dictionary as argument, with proper style keys and values as if they were integrated to GeoJSON.
You can generate an appropriate dictionary with "OGCObject class >> #createStyleDictionary:" method, which takes an array with the four string values in following order: #( <fill> <fill-opacity> <stroke> <stroke-width>). For example: #('orange' '0.6' 'black' '2').
Write "nil" if you don't want to change one of given parameters. For example, #('green' nil nil nil) will only change filling color, and keep default values for other style parameters.
This is an example applied on "GeoJSONExamples class >> #aMultiPolygon":
Apply a style with feature conditions with a method
You can decide to change the appearance of some features according to custom rules.
To apply a style under conditions, you can call "OGCObject>>#applyStyle:ifFeature:" method.
This method takes:
first, a style dictionary - as seen in previous paragraph
then, a block closure which takes a feature as variable and defines conditions that the features should respect to get given style applied
NOTE: to run the following example, you need to load NeoCSV
To study an example with metropolitan French regions, launch
It displays French regions with a different color according to the number of inhabitants:
red if regional population > 10 000 000 inhabitants
orange if regional population > 5 000 000 inhabitants
Apply a style with feature conditions with a CSV data file
You can load a CSV file with practical data to use for styling!
It's a way easier and faster than coding a condition block closure with the method we present above.
You have 3 different styling types.
[ TO DO ] Classification with tags
A given color is applied when the value of a given property equals to a given tag
[ TO DO ] Classification with numbers
A color is applied when the value of a given property is found in a range of given numerical values
Continuous coloration with numbers
The opacity changes proportionally to the numerical value of a given property
Use "OGCObject>>#applyContinuousColorationOn:withFeatureData:withAssociateKey:withColor:" method, with following arguments:
apply continuous coloration on: the data key to use from your CSV
with feature data: your CSV as a parsed object (you can use NeoCSV Pharo package)
with associate key: the key which is common to feature properties and your CSV, used to join them
with color: the color to scale for display
This is an example with the number of cinema screens per metropolitan French region.
We applied especially here:
model applyContinuousColorationOn: 'nbEcrans' withFeatureData: csv withAssociateKey: 'code' withColor: 'blue'.
You can display it launching "GeoJSONExamples class>>#nbCinemaScreensPerFrenchRegion".
You can also display a continuous coloration per French region, based on the number of cinema entries ("GeoJSONExamples class>>#millionNumberOfEntriesPerFrenchRegion") or the average profit per entry in € ("GeoJSONExamples class>>#averageProfitPerEntryPerFrenchRegion").