Changeset 34898 in osm for applications


Ignore:
Timestamp:
2019-02-24T20:31:40+01:00 (6 years ago)
Author:
donvip
Message:

fix #josm13843 - Not properly loading attributes from multipart objects (patch by openbrian)

Location:
applications/editors/josm/plugins/opendata
Files:
5 added
2 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpReader.java

    r34452 r34898  
    116116            }
    117117
    118             OsmPrimitive primitive = null;
    119 
    120             if (geometry.getValue() instanceof Point) {
    121                 primitive = createOrGetEmptyNode((Point) geometry.getValue());
    122 
    123             } else if (geometry.getValue() instanceof GeometryCollection) { // Deals with both MultiLineString and MultiPolygon
    124                 GeometryCollection mp = (GeometryCollection) geometry.getValue();
    125                 int nGeometries = mp.getNumGeometries();
    126                 if (nGeometries < 1) {
    127                     Logging.error("empty geometry collection found");
    128                 } else {
    129                     Relation r = null;
    130                     Way w = null;
    131 
    132                     for (int i = 0; i < nGeometries; i++) {
    133                         Geometry g = mp.getGeometryN(i);
    134                         if (g instanceof Polygon) {
    135                             Polygon p = (Polygon) g;
    136                             // Do not create relation if there's only one polygon without interior ring
    137                             // except if handler prefers it
    138                             if (r == null && (nGeometries > 1 || p.getNumInteriorRing() > 0 ||
    139                                     (handler != null && handler.preferMultipolygonToSimpleWay()))) {
    140                                 r = createMultipolygon();
    141                             }
    142                             w = createOrGetWay(p.getExteriorRing());
    143                             if (r != null) {
    144                                 addWayToMp(r, "outer", w);
    145                                 for (int j = 0; j < p.getNumInteriorRing(); j++) {
    146                                     addWayToMp(r, "inner", createOrGetWay(p.getInteriorRingN(j)));
    147                                 }
    148                             }
    149                         } else if (g instanceof LineString) {
    150                             w = createOrGetWay((LineString) g);
    151                         } else if (g instanceof Point) {
    152                             // Some belgian data sets hold points into collections ?!
    153                             readNonGeometricAttributes(feature, createOrGetNode((Point) g));
    154                         } else {
    155                             Logging.error("unsupported geometry : "+g);
    156                         }
    157                     }
    158                     primitive = r != null ? r : w;
     118            Object geomObject = geometry.getValue();
     119            if (geomObject instanceof Point) {  // TODO: Support LineString and Polygon.
     120                // Sure you could have a Set of 1 object and join these 2 branches of
     121                // code, but I feel there would be a performance hit.
     122                OsmPrimitive primitive = createOrGetEmptyNode((Point) geomObject);
     123                readNonGeometricAttributes(feature, primitive);
     124            } else if (geomObject instanceof GeometryCollection) { // Deals with both MultiLineString and MultiPolygon
     125                Set<OsmPrimitive> primitives = processGeometryCollection((GeometryCollection) geomObject);
     126                for (OsmPrimitive prim : primitives) {
     127                    readNonGeometricAttributes(feature, prim);
    159128                }
    160129            } else {
     
    164133                Logging.debug("\tdescriptor: "+desc);
    165134                Logging.debug("\tname: "+geometry.getName());
    166                 Logging.debug("\tvalue: "+geometry.getValue());
     135                Logging.debug("\tvalue: "+geomObject);
    167136                Logging.debug("\tid: "+geometry.getIdentifier());
    168137                Logging.debug("-------------------------------------------------------------");
    169138            }
    170 
    171             if (primitive != null) {
    172                 // Read primitive non geometric attributes
    173                 readNonGeometricAttributes(feature, primitive);
    174             }
    175         }
     139        }
     140    }
     141
     142    protected Set<OsmPrimitive> processGeometryCollection(GeometryCollection gc) throws TransformException {
     143        // A feture may be a collection.  This set holds the items of the collection.
     144        Set<OsmPrimitive> primitives = new HashSet<>();
     145        int nGeometries = gc.getNumGeometries();
     146        if (nGeometries < 1) {
     147            Logging.error("empty geometry collection found");
     148        } else {
     149            // Create the primitive "op" and add it to the set of primitives.
     150            for (int i = 0; i < nGeometries; i++) {
     151                OsmPrimitive op = null;
     152                Geometry g = gc.getGeometryN(i);
     153                if (g instanceof Polygon) {
     154                    Relation r = (Relation) op;
     155                    Polygon p = (Polygon) g;
     156                    // Do not create relation if there's only one polygon without interior ring
     157                    // except if handler prefers it
     158                    if (r == null && (nGeometries > 1 || p.getNumInteriorRing() > 0 ||
     159                            (handler != null && handler.preferMultipolygonToSimpleWay()))) {
     160                        r = createMultipolygon();
     161                    }
     162                    if (r != null) {
     163                        addWayToMp(r, "outer", createOrGetWay(p.getExteriorRing()));
     164                        for (int j = 0; j < p.getNumInteriorRing(); j++) {
     165                            addWayToMp(r, "inner", createOrGetWay(p.getInteriorRingN(j)));
     166                        }
     167                    }
     168                } else if (g instanceof LineString) {
     169                    op = createOrGetWay((LineString) g);
     170                } else if (g instanceof Point) {
     171                    op = createOrGetNode((Point) g);
     172                } else {
     173                    Logging.error("unsupported geometry : "+g);
     174                }
     175                primitives.add(op);
     176            }
     177        }
     178        return primitives;
    176179    }
    177180
  • applications/editors/josm/plugins/opendata/test/unit/org/openstreetmap/josm/plugins/opendata/core/io/geographic/ShpReaderTest.java

    r34153 r34898  
    22package org.openstreetmap.josm.plugins.opendata.core.io.geographic;
    33
     4import static org.junit.Assert.assertEquals;
    45import static org.junit.Assert.assertFalse;
    56import static org.junit.Assert.assertNotNull;
     
    910import java.io.FileInputStream;
    1011import java.io.InputStream;
     12import java.util.Collection;
    1113
    1214import org.junit.Ignore;
     
    1618import org.openstreetmap.josm.data.coor.LatLon;
    1719import org.openstreetmap.josm.data.osm.Node;
     20import org.openstreetmap.josm.data.osm.Way;
    1821import org.openstreetmap.josm.plugins.opendata.core.io.NonRegFunctionalTests;
    1922import org.openstreetmap.josm.testutils.JOSMTestRules;
     
    8588        }
    8689    }
     90
     91    /**
     92     * Non-regression test for ticket <a href="https://josm.openstreetmap.de/ticket/12843">#12843</a>
     93     * @throws Exception if an error occurs during reading
     94     */
     95    @Test
     96    public void testTicket12843() throws Exception {
     97        File file = new File(TestUtils.getRegressionDataFile(12843, "test.shp"));
     98        try (InputStream is = new FileInputStream(file)) {
     99            Collection<Way> ways = ShpReader.parseDataSet(is, file, null, null).getWays();
     100            assertFalse(ways.isEmpty());
     101            for (Way way : ways) {
     102                assertEquals("Test", way.get("name"));
     103            }
     104        }
     105    }
    87106}
Note: See TracChangeset for help on using the changeset viewer.