Skip to content

Commit

Permalink
More geojson types processing implemented according to geojson spec
Browse files Browse the repository at this point in the history
  • Loading branch information
Larry0ua committed Nov 9, 2015
1 parent 45166c2 commit a9b41f1
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 121 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ A plugin for displaying geodata stored in a [geojson](https://geojson.org/) form

## Status

[![Build Status](https://travis-ci.org/matthieun/josm-geojson.svg?branch=master)](https://travis-ci.org/matthieun/josm-geojson)
<!-- [![Build Status](https://travis-ci.org/matthieun/josm-geojson.svg?branch=master)](https://travis-ci.org/matthieun/josm-geojson) -->

## Build

Expand Down
7 changes: 3 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,16 @@ group = 'org.openstreetmap.josm.plugins'
version = '0.0.0-SNAPSHOT'

// Change JOSM version (if needed) before you build
project.ext.josm_version='8599'
project.ext.josm_version='8969'
project.ext.josm_location='download'
sourceCompatibility = "1.7"
targetCompatibility = "1.7"

repositories
{ mavenCentral() }

repositories {
mavenCentral()
flatDir(dirs: file('lib/'))
}

configurations {
provided
}
Expand Down
2 changes: 1 addition & 1 deletion dependencies.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
project.ext.versions = [
junit: '4.8.2',
geojsonjackson: '1.5',
geojsonjackson: '1.5.1',
jackson: '2.5.4',
]

Expand Down
276 changes: 161 additions & 115 deletions src/main/java/org/openstreetmap/josm/plugins/geojson/DataSetBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,152 +6,198 @@
import java.util.Map.Entry;
import java.util.TreeMap;

import org.geojson.Feature;
import org.geojson.FeatureCollection;
import org.geojson.GeoJsonObject;
import org.geojson.LineString;
import org.geojson.LngLatAlt;
import org.geojson.Point;
import org.geojson.Polygon;
import org.geojson.*;
import org.openstreetmap.josm.data.Bounds;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.data.osm.Way;
import org.openstreetmap.josm.data.osm.*;

/**
* @author matthieun
*/
public class DataSetBuilder
{
public class DataSetBuilder {
/**
* @author matthieun
*/
public static class BoundedDataSet
{
public static class BoundedDataSet {
private final DataSet dataSet;
private final Bounds bounds;

public BoundedDataSet(final DataSet dataSet, final Bounds bounds)
{
public BoundedDataSet(final DataSet dataSet, final Bounds bounds) {
this.dataSet = dataSet;
this.bounds = bounds;
}

public Bounds getBounds()
{
public Bounds getBounds() {
return this.bounds;
}

public DataSet getDataSet()
{
public DataSet getDataSet() {
return this.dataSet;
}
}

public BoundedDataSet build(final GeoJsonObject data)
{
DataSet dataSet = null;
public BoundedDataSet build(final GeoJsonObject data) {
DataSet dataSet = new DataSet();
if (data instanceof FeatureCollection) {
processFeatureCollection(dataSet, (FeatureCollection) data);
} else if (data instanceof GeometryCollection) {
processGeometryCollection(dataSet, null, (GeometryCollection) data);
} else if (data instanceof Feature) {
processFeature(dataSet, (Feature) data);
} else {
processGeometry(dataSet, null, data);
}

Bounds bounds = null;
dataSet = new DataSet();
if (data instanceof FeatureCollection)
{
final FeatureCollection fc = (FeatureCollection) data;
for (final Feature feature : fc)
{
final GeoJsonObject geometry = feature.getGeometry();
if (geometry instanceof Point)
{
final LngLatAlt coordinate = ((Point) geometry).getCoordinates();
final LatLon latlon = new LatLon(coordinate.getLatitude(),
coordinate.getLongitude());
final Node node = new Node(latlon);
node.setKeys(getTags(feature));
dataSet.addPrimitive(node);
}
if (geometry instanceof LineString)
{
final Way way = new Way();

final List<LngLatAlt> coordinates = ((LineString) geometry).getCoordinates();
final List<Node> nodes = new ArrayList<Node>(coordinates.size());
for (final LngLatAlt lngLatAlt : coordinates)
{
final LatLon latlon = new LatLon(lngLatAlt.getLatitude(),
lngLatAlt.getLongitude());

if (bounds == null)
{
bounds = new Bounds(latlon);
}
else
{
bounds.extend(latlon);
}

final Node node = new Node(latlon);
dataSet.addPrimitive(node);
nodes.add(node);
}
way.setNodes(nodes);
way.setKeys(getTags(feature));
dataSet.addPrimitive(way);
}
else if (geometry instanceof Polygon)
{
final Way way = new Way();

final List<List<LngLatAlt>> coordinates = ((Polygon) geometry).getCoordinates();
final List<Node> nodes = new ArrayList<Node>(coordinates.size());
int counter = 0;
Node first = null;
for (final List<LngLatAlt> coordinateList : coordinates)
{
for (final LngLatAlt lngLatAlt : coordinateList)
{
final LatLon latlon = new LatLon(lngLatAlt.getLatitude(),
lngLatAlt.getLongitude());

if (bounds == null)
{
bounds = new Bounds(latlon);
}
else
{
bounds.extend(latlon);
}

final Node node = new Node(latlon);
dataSet.addPrimitive(node);
nodes.add(node);
if (counter == 0)
{
first = node;
}
counter++;
}
}
if (first != null)
{
nodes.add(first);
}
way.setNodes(nodes);
way.setKeys(getTags(feature));
dataSet.addPrimitive(way);
}
}
for (OsmPrimitive osmPrimitive : dataSet.allPrimitives()) {
bounds = mergeBounds(bounds, osmPrimitive);
}
return new BoundedDataSet(dataSet, bounds);
}

private Map<String, String> getTags(final Feature feature)
{
private void processFeatureCollection(DataSet dataSet, FeatureCollection data) {
for (final Feature feature : data) {
processFeature(dataSet, feature);
}
}

private void processGeometryCollection(DataSet dataSet, Feature feature, GeometryCollection geometryCollection) {
for (GeoJsonObject geometry : geometryCollection) {
processGeometry(dataSet, feature, geometry);
}
}

private void processFeature(DataSet dataSet, Feature feature) {
processGeometry(dataSet, feature, feature.getGeometry());
}

private void processMultiPoint(DataSet dataSet, Feature feature, MultiPoint multiPoint) {
for (LngLatAlt point : multiPoint.getCoordinates()) {
processPoint(dataSet, feature, point);
}
}

private void processGeometry(DataSet dataSet, Feature feature, GeoJsonObject geometry) {
if (geometry instanceof Feature) {
processGeometry(dataSet, (Feature) geometry, ((Feature) geometry).getGeometry());
} else {
if (geometry instanceof Point) {
processPoint(dataSet, feature, ((Point) geometry).getCoordinates());
} else if (geometry instanceof LineString) {
processLineString(dataSet, feature, ((LineString) geometry).getCoordinates());
} else if (geometry instanceof Polygon) {
processPolygon(dataSet, feature, ((Polygon) geometry).getCoordinates());
} else if (geometry instanceof MultiPoint) {
processMultiPoint(dataSet, feature, (MultiPoint) geometry);
} else if (geometry instanceof MultiLineString) {
processMultiLineString(dataSet, feature, (MultiLineString) geometry);
} else if (geometry instanceof MultiPolygon) {
processMultiPolygon(dataSet, feature, (MultiPolygon) geometry);
} else if (geometry instanceof GeometryCollection) {
processGeometryCollection(dataSet, feature, (GeometryCollection) geometry);
}
}
}

private void processMultiPolygon(DataSet dataSet, Feature feature, MultiPolygon geometry) {
for (List<List<LngLatAlt>> polygon : geometry.getCoordinates()) {
processPolygon(dataSet, feature, polygon);
}
}

private void processMultiLineString(DataSet dataSet, Feature feature, MultiLineString multiLineString) {
for (List<LngLatAlt> coordinates : multiLineString.getCoordinates()) {
processLineString(dataSet, feature, coordinates);
}
}

private void processPoint(DataSet dataSet, Feature feature, LngLatAlt geometry) {
final Node node = createNode(dataSet, geometry);

fillTagsFromFeature(feature, node);
}

private void processLineString(DataSet dataSet, Feature feature, List<LngLatAlt> coordinates) {
final Way way = createWay(dataSet, coordinates);

fillTagsFromFeature(feature, way);
}

private void processPolygon(DataSet dataSet, Feature feature, List<List<LngLatAlt>> coordinates) {
if (coordinates.size() == 1) {
// create simple way
createWay(dataSet, coordinates.get(0));

} else if (coordinates.size() > 1) {
// create multipolygon
final Relation multipolygon = new Relation();
multipolygon.put("type", "multipolygon");
Way way = createWay(dataSet, coordinates.get(0));
multipolygon.addMember(new RelationMember("outer", way));

for (List<LngLatAlt> interiorRings : coordinates.subList(1, coordinates.size())) {
way = createWay(dataSet, interiorRings);
multipolygon.addMember(new RelationMember("inner", way));
}
fillTagsFromFeature(feature, multipolygon);
dataSet.addPrimitive(multipolygon);
}
}

private void fillTagsFromFeature(Feature feature, OsmPrimitive primitive) {
if (feature != null) {
primitive.setKeys(getTags(feature));
}
}

private Node createNode(DataSet dataSet, LngLatAlt point) {
final LatLon latlon = new LatLon(point.getLatitude(), point.getLongitude());
Node node = new Node(latlon);

dataSet.addPrimitive(node);

return node;
}

private Way createWay(DataSet dataSet, List<LngLatAlt> coordinates) {
final Way way = new Way();

final List<Node> nodes = new ArrayList<>(coordinates.size());

for (final LngLatAlt point : coordinates) {
final Node node = createNode(dataSet, point);

nodes.add(node);
}
way.setNodes(nodes);

dataSet.addPrimitive(way);

return way;
}

private Map<String, String> getTags(final Feature feature) {
final Map<String, Object> properties = feature.getProperties();
final Map<String, String> tags = new TreeMap<String, String>();
for (final Entry<String, Object> entry : properties.entrySet())
{
final Map<String, String> tags = new TreeMap<>();
for (final Entry<String, Object> entry : properties.entrySet()) {
tags.put(entry.getKey(), entry.getValue().toString());
}
return tags;
}

private Bounds mergeBounds(Bounds bounds, OsmPrimitive osmPrimitive) {
if (osmPrimitive instanceof Node) { // ways and relations consist of nodes that are already in the dataset
bounds = mergeBounds(bounds, ((Node)osmPrimitive).getCoor());
}
return bounds;
}

private Bounds mergeBounds(Bounds bounds, LatLon coords) {
if (bounds == null) {
return new Bounds(coords);
} else {
bounds.extend(coords);
return bounds;
}
}
}

0 comments on commit a9b41f1

Please sign in to comment.