tordanik / OSM2World

converter that creates three-dimensional models of the world from OpenStreetMap data
http://osm2world.org/
GNU Lesser General Public License v3.0
566 stars 124 forks source link

coordinate frames of the building footprints #215

Closed christopher-hsu closed 10 months ago

christopher-hsu commented 10 months ago

Hi, I am looking to extract the building footprints in the coordinate frame you define in OSM2World/tree/master/src/main/java/org/osm2world/core/map_data/creation/MetricMapProjection.java (I assume this is what you are doing under the hood in your application).

Is there a simple way of extruding this data in your metric map projection coordinate reference frame? A workaround I am trying is by attempting to recreate this projection with standard map tools such as taking the osm data and converting to crs "EPSG:3857" and translating the data to the originX and originY in the same crs, however I am not getting the exact same x,y.

Any advice as to how best to get the building footprints would be greatly appreciated. Maybe I need to just access the .obj file outputted from your application and work with that data instead?

tordanik commented 10 months ago

I don't think there's an easy built-in way to do this at the moment. However, if you're willing to build a small Java tool with OSM2World as a dependency, you can output the projected building geometry in a format of your liking with something like this:

import java.io.File;
import java.io.IOException;

import org.apache.commons.configuration.BaseConfiguration;
import org.osm2world.core.map_data.creation.MetricMapProjection;
import org.osm2world.core.map_data.creation.OSMToMapDataConverter;
import org.osm2world.core.map_data.data.MapArea;
import org.osm2world.core.map_data.data.MapData;
import org.osm2world.core.osm.creation.OSMFileReader;

import de.topobyte.osm4j.core.resolve.EntityNotFoundException;

public class BuildingProjectionMain {

    public static void main(String[] args) throws IOException, EntityNotFoundException {

        var inputFile = new File("path_to_your_file.osm");
        var osmData = new OSMFileReader(inputFile).getData();
        var origin = osmData.getCenter();
        var mapProjection = new MetricMapProjection(origin);
        var converter = new OSMToMapDataConverter(mapProjection, new BaseConfiguration());

        MapData mapData = converter.createMapData(osmData, null);

        for (MapArea area : mapData.getMapAreas()) {
            if (area.getTags().containsKey("building")) {
                System.out.println(area + ": " + area.getOuterPolygon());
            }
        }

    }

}
christopher-hsu commented 10 months ago

Thank you for the reply, I ended up rewriting your projection conversions in python and its working well!

Do you have any references as to where your version of the mercator projections come from?

tordanik commented 10 months ago

Do you have any references as to where your version of the mercator projections come from?

I'm not sure, that projection class has roots in code from over a decade ago and has been modified by several contributors since. To be honest, I didn't even remember that this MapProjection implementation rather than OrthographicAzimuthalMapProjection is still what is used by default. The projection code really needs some love.

Good to hear that you were able to find a solution, though. :)