Ignore:
Timestamp:
2017-09-24T21:25:19+02:00 (7 years ago)
Author:
donvip
Message:

Edigeo: initial mapping of PCI=>OSM objects

Location:
applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/EdigeoFileVEC.java

    r33661 r33662  
    55import java.nio.file.Path;
    66import java.util.ArrayList;
     7import java.util.Arrays;
    78import java.util.Collections;
    89import java.util.HashMap;
     
    1011import java.util.Map;
    1112import java.util.Objects;
     13import java.util.function.BiConsumer;
    1214import java.util.function.Predicate;
    1315import java.util.stream.Collectors;
     
    2022import org.openstreetmap.josm.data.osm.Node;
    2123import org.openstreetmap.josm.data.osm.OsmPrimitive;
    22 import org.openstreetmap.josm.data.osm.Tag;
    2324import org.openstreetmap.josm.data.osm.Way;
    2425import org.openstreetmap.josm.data.projection.Projection;
     
    3637import org.openstreetmap.josm.plugins.fr.cadastre.edigeo.EdigeoRecord.Nature;
    3738import org.openstreetmap.josm.tools.Logging;
     39import org.openstreetmap.josm.tools.Pair;
    3840
    3941/**
     
    145147            return attributeValues.get(i);
    146148        }
     149
     150        public boolean hasScdIdentifier(String id) {
     151            return scdRef.identifier.equals(id);
     152        }
    147153    }
    148154
     
    422428
    423429    private static final List<Predicate<ObjectBlock>> ignoredObjects = new ArrayList<>();
     430    private static final List<Pair<Predicate<ObjectBlock>, BiConsumer<ObjectBlock, OsmPrimitive>>> postProcessors = new ArrayList<>();
    424431
    425432    /**
    426433     * Adds a predicate to ignore a special type of object.
    427434     * @param predicate defines how to identify the object to ignore
    428      * @return {@code true}
    429      */
    430     public static boolean addIgnoredObject(Predicate<ObjectBlock> predicate) {
    431         return ignoredObjects.add(Objects.requireNonNull(predicate, "predicate"));
     435     */
     436    public static void addIgnoredObject(Predicate<ObjectBlock> predicate) {
     437        ignoredObjects.add(Objects.requireNonNull(predicate, "predicate"));
    432438    }
    433439
     
    435441     * Adds a predicate to ignore a special type of object based on a key/value attribute.
    436442     * @param key attribute key
    437      * @param value attribute value
    438      * @return {@code true}
    439      */
    440     public static boolean addIgnoredObject(String key, String value) {
    441         return addIgnoredObject(o -> {
     443     * @param values attribute values
     444     */
     445    public static void addIgnoredObject(String key, String... values) {
     446        addIgnoredObject(predicate(key, values));
     447    }
     448
     449    private static Predicate<ObjectBlock> predicate(String key, String... values) {
     450        return o -> {
     451            List<String> vals = Arrays.asList(values);
    442452            for (int i = 0; i < o.nAttributes; i++) {
    443453                if (key.equals(o.attributeDefs.get(i).identifier)
    444                         && value.equals(o.attributeValues.get(i))) {
     454                        && (vals.isEmpty() || vals.contains(o.attributeValues.get(i)))) {
    445455                    return true;
    446456                }
    447457            }
    448458            return false;
    449         });
     459        };
     460    }
     461
     462    /**
     463     * Adds a data postprocessor.
     464     * @param consumer consumer that will update OSM primitive accordingly
     465     * @param predicate predicate to match
     466     */
     467    public static void addObjectPostProcessor(BiConsumer<ObjectBlock, OsmPrimitive> consumer, Predicate<ObjectBlock> predicate) {
     468        postProcessors.add(new Pair<>(Objects.requireNonNull(predicate, "predicate"), Objects.requireNonNull(consumer, "consumer")));
     469    }
     470
     471    /**
     472     * Adds a data postprocessor based on a key/value attribute.
     473     * @param consumer consumer that will update OSM primitive accordingly
     474     * @param key attribute key
     475     * @param values attribute values
     476     */
     477    public static void addObjectPostProcessor(BiConsumer<ObjectBlock, OsmPrimitive> consumer, String key, String... values) {
     478        postProcessors.add(new Pair<>(predicate(key, values), Objects.requireNonNull(consumer, "consumer")));
     479    }
     480
     481    /**
     482     * Adds a data postprocessor based on a SYM_id specific value.
     483     * @param consumer consumer that will update OSM primitive accordingly
     484     * @param symId value for "SYM_id" attribute.
     485     * @param keyValues OSM attribute key/values (int the form {@code foo=bar;bar=baz})
     486     */
     487    public static void addObjectPostProcessor(String symId, String keyValues) {
     488        postProcessors.add(new Pair<>(predicate("SYM_id", symId), (o, p) -> {
     489            p.remove("SYM_id");
     490            for (String tag : keyValues.split(";")) {
     491                String[] kv = tag.split("=");
     492                p.put(kv[0], kv[1]);
     493            }
     494        }));
    450495    }
    451496
     
    468513
    469514    private static BBox around(LatLon ll) {
    470         final double r = 1e-7;
     515        final double r = 1e-6;
    471516        return new BBox(ll.getX() - r, ll.getY() - r, ll.getX() + r, ll.getY() + r);
    472517    }
     
    489534        for (ObjectBlock obj : getObjects()) {
    490535            if (!ignoredObjects.stream().anyMatch(p -> p.test(obj))) {
     536                OsmPrimitive p;
    491537                switch (obj.scdRef.kind) {
    492                     case POINT: fillPoint(ds, proj, obj, obj.getConstructionRelations(), obj.getSemanticRelations()); break;
    493                     case LINE: fillLine(ds, proj, obj, obj.getConstructionRelations(), obj.getSemanticRelations()); break;
    494                     case AREA: fillArea(ds, proj, obj, obj.getConstructionRelations(), obj.getSemanticRelations()); break;
    495                     case COMPLEX: break; // TODO (not used in PCI)
     538                    case POINT: p = fillPoint(ds, proj, obj, obj.getConstructionRelations(), obj.getSemanticRelations()); break;
     539                    case LINE: p = fillLine(ds, proj, obj, obj.getConstructionRelations(), obj.getSemanticRelations()); break;
     540                    case AREA: p = fillArea(ds, proj, obj, obj.getConstructionRelations(), obj.getSemanticRelations()); break;
     541                    case COMPLEX: // TODO (not used in PCI)
    496542                    default: throw new IllegalArgumentException(obj.toString());
    497543                }
     544                if (p != null) {
     545                    for (Pair<Predicate<ObjectBlock>, BiConsumer<ObjectBlock, OsmPrimitive>> e : postProcessors) {
     546                        if (e.a.test(obj)) {
     547                            e.b.accept(obj, p);
     548                        }
     549                    }
     550                }
    498551            }
    499552        }
     
    501554    }
    502555
    503     private static void addPrimitiveAndTags(DataSet ds, ObjectBlock obj, OsmPrimitive osm) {
     556    private static <T extends OsmPrimitive> T addPrimitiveAndTags(DataSet ds, ObjectBlock obj, T osm) {
    504557        for (int i = 0; i < obj.nAttributes; i++) {
    505             osm.put(new Tag(obj.attributeDefs.get(i).identifier, obj.attributeValues.get(i)));
    506         }
    507         ds.addPrimitive(osm);
     558            osm.put(obj.attributeDefs.get(i).identifier, obj.attributeValues.get(i));
     559        }
     560        if (osm.getDataSet() == null) {
     561            ds.addPrimitive(osm);
     562        }
     563        return osm;
    508564    }
    509565
     
    527583    }
    528584
    529     private static void fillPoint(DataSet ds, Projection proj, ObjectBlock obj,
     585    private static Node fillPoint(DataSet ds, Projection proj, ObjectBlock obj,
    530586            List<RelationBlock> constructionRelations, List<RelationBlock> semanticRelations) {
    531587        assert constructionRelations.size() == 1 : constructionRelations;
    532         List<NodeBlock> nodes = extract(NodeBlock.class, constructionRelations, RelationKind.IS_MADE_OF);
    533         assert nodes.size() == 1 : nodes;
    534         NodeBlock nb = nodes.get(0);
     588        List<NodeBlock> blocks = extract(NodeBlock.class, constructionRelations, RelationKind.IS_MADE_OF);
     589        assert blocks.size() == 1 : blocks;
     590        NodeBlock nb = blocks.get(0);
    535591        assert nb.nAttributes == 0;
    536592        LatLon ll = proj.eastNorth2latlon(nb.getCoordinate());
    537         //if (ds.searchNodes(around(ll)).isEmpty()) {
    538         addPrimitiveAndTags(ds, obj, new Node(ll));
    539         //}
    540     }
    541 
    542     private static void fillLine(DataSet ds, Projection proj, ObjectBlock obj,
     593        List<Node> nodes = ds.searchNodes(around(ll));
     594        assert nodes.size() <= 1;
     595        Node n = nodes.isEmpty() ? new Node(ll) : nodes.get(0);
     596        return addPrimitiveAndTags(ds, obj, n);
     597    }
     598
     599    private static Way fillLine(DataSet ds, Projection proj, ObjectBlock obj,
    543600            List<RelationBlock> constructionRelations, List<RelationBlock> semanticRelations) {
    544601        assert constructionRelations.size() >= 1 : constructionRelations;
     
    554611            if (newArcs.size() != 1) {
    555612                Logging.warn("Unable to process geometry of: " + obj);
    556                 return;
     613                return null;
    557614            }
    558615            while (newArcs.size() < arcs.size()) {
     
    579636        }
    580637        assert w.getNodesCount() >= 2;
    581         addPrimitiveAndTags(ds, obj, w);
    582     }
    583 
    584     private static void fillArea(DataSet ds, Projection proj, ObjectBlock obj,
     638        return addPrimitiveAndTags(ds, obj, w);
     639    }
     640
     641    private static OsmPrimitive fillArea(DataSet ds, Projection proj, ObjectBlock obj,
    585642            List<RelationBlock> constructionRelations, List<RelationBlock> semanticRelations) {
    586643        assert constructionRelations.size() >= 1 : constructionRelations;
    587644        // TODO
     645        return null;
    588646    }
    589647
  • applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/pci/EdigeoPciReader.java

    r33660 r33662  
    66import java.io.InputStream;
    77import java.nio.file.Path;
     8import java.util.Arrays;
     9import java.util.HashMap;
     10import java.util.List;
     11import java.util.Map;
     12import java.util.Map.Entry;
    813
    914import org.openstreetmap.josm.data.osm.DataSet;
    1015import org.openstreetmap.josm.data.osm.DataSet.UploadPolicy;
     16import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1117import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    1218import org.openstreetmap.josm.io.AbstractReader;
     
    2026public class EdigeoPciReader extends AbstractReader {
    2127
     28    private static final Map<String, List<String>> highways = new HashMap<>();
    2229    static {
    23         EdigeoFileVEC.addIgnoredObject("SYM_id", "31");
     30        highways.put("motorway", Arrays.asList("Autoroute"));
     31        highways.put("trunk", Arrays.asList("Rocade"));
     32        highways.put("secondary", Arrays.asList("Avenue", "Boulevard", "Allee", "Allée", "Allees", "Allées", "Pont", "Port", "Route"));
     33        highways.put("residential", Arrays.asList("Chemin", "Impasse", "Place", "Rue", "Quai", "Voie", "Grand Rue"));
     34
     35        EdigeoFileVEC.addIgnoredObject("SYM_id",
     36                "31", // Connecting arrows between parcelles and numbers
     37                "62", // "Sports ground, small streams". What the fuck France?
     38                "64"  // "parking, terrace, overhang". What the fuck France?
     39        );
     40
     41        EdigeoFileVEC.addObjectPostProcessor("19", "boundary=administrative;admin_level=8"); // Municipality limit trigger
     42        EdigeoFileVEC.addObjectPostProcessor("21", "highway=road"); // Path
     43        EdigeoFileVEC.addObjectPostProcessor("39", "barrier=wall"); // Common wall
     44        EdigeoFileVEC.addObjectPostProcessor("40", "barrier=wall"); // Non-adjacent wall
     45        EdigeoFileVEC.addObjectPostProcessor("45", "barrier=hedge"); // Common hedge
     46        EdigeoFileVEC.addObjectPostProcessor("46", "barrier=hedge"); // Non-adjacent hedge
     47
     48        EdigeoFileVEC.addObjectPostProcessor((o, p) -> {
     49            StringBuffer sb = new StringBuffer(p.get("TEX_id").trim());
     50            p.remove("TEX_id");
     51            for (String t : Arrays.asList("TEX2_id", "TEX3_id", "TEX4_id", "TEX5_id", "TEX6_id", "TEX7_id", "TEX8_id", "TEX9_id")) {
     52                String v = p.get(t);
     53                if (v == null) {
     54                    break;
     55                }
     56                sb.append(' ').append(v.trim());
     57                p.remove(t);
     58            }
     59            p.put("name", sb.toString());
     60        }, "TEX_id");
     61
     62        EdigeoFileVEC.addObjectPostProcessor((o, p) -> {
     63            p.put("highway", "road");
     64            String name = p.get("name");
     65            if (name != null && name.contains(" ")) {
     66                String[] words = name.split(" ");
     67                if (!setCorrectHighway(p, words)) {
     68                    if (highways.values().stream().anyMatch(l -> l.contains(words[words.length - 1]))) {
     69                        String[] newWords = new String[words.length];
     70                        newWords[0] = words[words.length - 1];
     71                        System.arraycopy(words, 0, newWords, 1, words.length - 1);
     72                        p.put("name", String.join(" ", newWords));
     73                        setCorrectHighway(p, newWords);
     74                    }
     75                }
     76            }
     77        }, o -> o.hasScdIdentifier("ZONCOMMUNI_id"));
     78    }
     79
     80    private static boolean setCorrectHighway(OsmPrimitive p, String[] words) {
     81        String type = words[0];
     82        for (Entry<String, List<String>> e : highways.entrySet()) {
     83            if (e.getValue().contains(type)) {
     84                p.put("highway", e.getKey());
     85                return true;
     86            }
     87        }
     88        return false;
    2489    }
    2590
Note: See TracChangeset for help on using the changeset viewer.