Changeset 8813 in josm


Ignore:
Timestamp:
2015-10-01T21:28:35+02:00 (4 years ago)
Author:
simon04
Message:

fix #10770 - GeoJSON export: allow to save coordinates in current map projection

Adds a *.proj.geojson exporter which writes the GeoJSON file with the currently set map projection.

Location:
trunk/src/org/openstreetmap/josm
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/ExtensionFileFilter.java

    r8510 r8813  
    44import java.io.File;
    55import java.util.ArrayList;
     6import java.util.Arrays;
    67import java.util.Collections;
    78import java.util.Comparator;
     
    4748        importers = new ArrayList<>();
    4849
    49         String[] importerNames = {
    50                 "org.openstreetmap.josm.io.OsmImporter",
    51                 "org.openstreetmap.josm.io.OsmGzipImporter",
    52                 "org.openstreetmap.josm.io.OsmZipImporter",
    53                 "org.openstreetmap.josm.io.OsmChangeImporter",
    54                 "org.openstreetmap.josm.io.GpxImporter",
    55                 "org.openstreetmap.josm.io.NMEAImporter",
    56                 "org.openstreetmap.josm.io.NoteImporter",
    57                 "org.openstreetmap.josm.io.OsmBzip2Importer",
    58                 "org.openstreetmap.josm.io.JpgImporter",
    59                 "org.openstreetmap.josm.io.WMSLayerImporter",
    60                 "org.openstreetmap.josm.io.AllFormatsImporter",
    61                 "org.openstreetmap.josm.io.session.SessionImporter"
    62         };
    63 
    64         for (String classname : importerNames) {
     50        final List<Class<? extends FileImporter>> importerNames = Arrays.asList(
     51                org.openstreetmap.josm.io.OsmImporter.class,
     52                org.openstreetmap.josm.io.OsmGzipImporter.class,
     53                org.openstreetmap.josm.io.OsmZipImporter.class,
     54                org.openstreetmap.josm.io.OsmChangeImporter.class,
     55                org.openstreetmap.josm.io.GpxImporter.class,
     56                org.openstreetmap.josm.io.NMEAImporter.class,
     57                org.openstreetmap.josm.io.NoteImporter.class,
     58                org.openstreetmap.josm.io.OsmBzip2Importer.class,
     59                org.openstreetmap.josm.io.JpgImporter.class,
     60                org.openstreetmap.josm.io.WMSLayerImporter.class,
     61                org.openstreetmap.josm.io.AllFormatsImporter.class,
     62                org.openstreetmap.josm.io.session.SessionImporter.class
     63        );
     64
     65        for (final Class<? extends FileImporter> importerClass : importerNames) {
    6566            try {
    66                 FileImporter importer = (FileImporter) Class.forName(classname).newInstance();
     67                FileImporter importer = importerClass.newInstance();
    6768                importers.add(importer);
    6869                MapView.addLayerChangeListener(importer);
     
    9293        exporters = new ArrayList<>();
    9394
    94         String[] exporterNames = {
    95                 "org.openstreetmap.josm.io.GpxExporter",
    96                 "org.openstreetmap.josm.io.OsmExporter",
    97                 "org.openstreetmap.josm.io.OsmGzipExporter",
    98                 "org.openstreetmap.josm.io.OsmBzip2Exporter",
    99                 "org.openstreetmap.josm.io.GeoJSONExporter",
    100                 "org.openstreetmap.josm.io.WMSLayerExporter",
    101                 "org.openstreetmap.josm.io.NoteExporter"
    102         };
    103 
    104         for (String classname : exporterNames) {
     95        final List<Class<? extends FileExporter>> exporterClasses = Arrays.asList(
     96                org.openstreetmap.josm.io.GpxExporter.class,
     97                org.openstreetmap.josm.io.OsmExporter.class,
     98                org.openstreetmap.josm.io.OsmGzipExporter.class,
     99                org.openstreetmap.josm.io.OsmBzip2Exporter.class,
     100                org.openstreetmap.josm.io.GeoJSONExporter.CurrentProjection.class, // needs to be considered earlier than GeoJSONExporter
     101                org.openstreetmap.josm.io.GeoJSONExporter.class,
     102                org.openstreetmap.josm.io.WMSLayerExporter.class,
     103                org.openstreetmap.josm.io.NoteExporter.class
     104        );
     105
     106        for (final Class<? extends FileExporter> exporterClass : exporterClasses) {
    105107            try {
    106                 FileExporter exporter = (FileExporter) Class.forName(classname).newInstance();
     108                FileExporter exporter = exporterClass.newInstance();
    107109                exporters.add(exporter);
    108110                MapView.addLayerChangeListener(exporter);
  • trunk/src/org/openstreetmap/josm/io/GeoJSONExporter.java

    r7937 r8813  
    1010import java.nio.file.Files;
    1111
     12import org.openstreetmap.josm.Main;
    1213import org.openstreetmap.josm.actions.ExtensionFileFilter;
     14import org.openstreetmap.josm.data.projection.Projection;
    1315import org.openstreetmap.josm.gui.layer.Layer;
    1416import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     17import org.openstreetmap.josm.gui.preferences.projection.ProjectionPreference;
     18import org.openstreetmap.josm.tools.Utils;
    1519
    1620public class GeoJSONExporter extends FileExporter {
    1721
     22    protected final Projection projection;
    1823    public static final ExtensionFileFilter FILE_FILTER = new ExtensionFileFilter(
    1924            "geojson,json", "geojson", tr("GeoJSON Files") + " (*.geojson *.json)");
     25    public static final ExtensionFileFilter FILE_FILTER_PROJECTED = new ExtensionFileFilter(
     26            "proj.geojson", "proj.geojson", tr("Projected GeoJSON Files") + " (*.proj.geojson)");
    2027
    2128    /**
    22      * Constructs a new {@code GeoJSONExporter}.
     29     * A GeoJSON exporter which obtains the current map projection when exporting ({@link #exportData(File, Layer)}).
     30     */
     31    public static class CurrentProjection extends GeoJSONExporter {
     32        public CurrentProjection() {
     33            super(FILE_FILTER_PROJECTED, null);
     34        }
     35    }
     36
     37    /**
     38     * Constructs a new {@code GeoJSONExporter} with WGS84 projection.
    2339     */
    2440    public GeoJSONExporter() {
    25         super(FILE_FILTER);
     41        this(FILE_FILTER, ProjectionPreference.wgs84.getProjection());
     42    }
     43
     44    private GeoJSONExporter(ExtensionFileFilter fileFilter, Projection projection) {
     45        super(fileFilter);
     46        this.projection = projection;
    2647    }
    2748
     
    2950    public void exportData(File file, Layer layer) throws IOException {
    3051        if (layer instanceof OsmDataLayer) {
    31             String json = new GeoJSONWriter((OsmDataLayer) layer).write();
     52            String json = new GeoJSONWriter((OsmDataLayer) layer, Utils.firstNonNull(projection, Main.getProjection())).write();
    3253            try (Writer out = Files.newBufferedWriter(file.toPath(), StandardCharsets.UTF_8)) {
    3354                out.write(json);
  • trunk/src/org/openstreetmap/josm/io/GeoJSONWriter.java

    r8510 r8813  
    1515
    1616import org.openstreetmap.josm.data.Bounds;
     17import org.openstreetmap.josm.data.coor.EastNorth;
    1718import org.openstreetmap.josm.data.coor.LatLon;
    1819import org.openstreetmap.josm.data.osm.DataSet;
     
    2425import org.openstreetmap.josm.data.osm.Way;
    2526import org.openstreetmap.josm.data.osm.visitor.PrimitiveVisitor;
     27import org.openstreetmap.josm.data.projection.Projection;
    2628import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    2729
     
    3133public class GeoJSONWriter {
    3234
    33     private OsmDataLayer layer;
     35    private final OsmDataLayer layer;
     36    private final Projection projection;
    3437    private static final boolean skipEmptyNodes = true;
    3538
     
    3740     * Constructs a new {@code GeoJSONWriter}.
    3841     * @param layer The OSM data layer to save
     42     * @param projection The projection to use for coordinates
    3943     */
    40     public GeoJSONWriter(OsmDataLayer layer) {
     44    public GeoJSONWriter(OsmDataLayer layer, Projection projection) {
    4145        this.layer = layer;
     46        this.projection = projection;
    4247    }
    4348
     
    6368            JsonObjectBuilder object = Json.createObjectBuilder()
    6469                    .add("type", "FeatureCollection")
     70                    .add("crs", Json.createObjectBuilder().add("type", "name").add("name", projection.toCode()))
    6571                    .add("generator", "JOSM");
    6672            appendLayerBounds(layer.data, object);
     
    7177    }
    7278
    73     private static class GeometryPrimitiveVisitor implements PrimitiveVisitor {
     79    private class GeometryPrimitiveVisitor implements PrimitiveVisitor {
    7480
    7581        private final JsonObjectBuilder geomObj;
     
    8490            LatLon ll = n.getCoor();
    8591            if (ll != null) {
    86                 geomObj.add("coordinates", getCoorArray(n.getCoor()));
     92                geomObj.add("coordinates", getCoorArray(Json.createArrayBuilder(), n.getCoor()));
    8793            }
    8894        }
     
    96102                    LatLon ll = n.getCoor();
    97103                    if (ll != null) {
    98                         array.add(getCoorArray(ll));
     104                        array.add(getCoorArray(Json.createArrayBuilder(), ll));
    99105                    }
    100106                }
     
    106112        public void visit(IRelation r) {
    107113        }
    108 
    109         private JsonArrayBuilder getCoorArray(LatLon c) {
    110             return Json.createArrayBuilder().add(c.lon()).add(c.lat());
    111         }
    112114    }
    113115
    114     protected static void appendPrimitive(OsmPrimitive p, JsonArrayBuilder array) {
     116    private JsonArrayBuilder getCoorArray(JsonArrayBuilder builder, LatLon c) {
     117        return getCoorArray(builder, projection.latlon2eastNorth(c));
     118    }
     119
     120    private JsonArrayBuilder getCoorArray(JsonArrayBuilder builder, EastNorth c) {
     121        return builder.add(c.getX()).add(c.getY());
     122    }
     123
     124    protected void appendPrimitive(OsmPrimitive p, JsonArrayBuilder array) {
    115125        if (p.isIncomplete()) {
    116126            return;
     
    136146    }
    137147
    138     protected static void appendLayerBounds(DataSet ds, JsonObjectBuilder object) {
     148    protected void appendLayerBounds(DataSet ds, JsonObjectBuilder object) {
    139149        if (ds != null) {
    140150            Iterator<Bounds> it = ds.getDataSourceBounds().iterator();
     
    149159    }
    150160
    151     protected static void appendBounds(Bounds b, JsonObjectBuilder object) {
     161    protected void appendBounds(Bounds b, JsonObjectBuilder object) {
    152162        if (b != null) {
    153             object.add("bbox", Json.createArrayBuilder()
    154                     .add(b.getMinLon()).add(b.getMinLat())
    155                     .add(b.getMaxLon()).add(b.getMaxLat()));
     163            JsonArrayBuilder builder = Json.createArrayBuilder();
     164            getCoorArray(builder, b.getMin());
     165            getCoorArray(builder, b.getMax());
     166            object.add("bbox", builder);
    156167        }
    157168    }
    158169
    159     protected static void appendLayerFeatures(DataSet ds, JsonObjectBuilder object) {
     170    protected void appendLayerFeatures(DataSet ds, JsonObjectBuilder object) {
    160171        JsonArrayBuilder array = Json.createArrayBuilder();
    161172        if (ds != null) {
Note: See TracChangeset for help on using the changeset viewer.