// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.transport; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.openstreetmap.josm.data.coor.EastNorth; 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.plugins.opendata.core.io.tabular.DefaultSpreadSheetHandler; import org.openstreetmap.josm.plugins.opendata.core.util.OdUtils; import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.DataGouvDataSetHandler; public class AeroportsHandler extends DataGouvDataSetHandler { private static final Pattern COOR_PATTERN = Pattern.compile( "(-?\\p{Digit}+)°\\p{Space}*(\\p{Digit}+)'\\p{Space}*(\\p{Digit}+)\\p{Space}*((Nord|Sud|Est|Ouest)?)", Pattern.CASE_INSENSITIVE); public AeroportsHandler() { super("Aéroports-français-coordonnées-géographiques-30382044"); setName("Aéroports"); setDownloadFileName("coordonn_es g_ographiques a_roports fran_ais v2.xls"); setSpreadSheetHandler(new InternalXlsHandler()); } @Override public boolean acceptsFilename(String filename) { return acceptsXlsFilename(filename, "coordonn_es g_ographiques a_roports fran_ais v2"); } @Override public void updateDataSet(DataSet ds) { for (Node n : ds.getNodes()) { n.put("aeroway", "aerodrome"); } } protected class InternalXlsHandler extends DefaultSpreadSheetHandler { public InternalXlsHandler() { setLineNumber(4); setHandlesProjection(true); } @Override public LatLon getCoor(EastNorth en, String[] fields) { Matcher x = COOR_PATTERN.matcher(fields[getXCol()]); Matcher y = COOR_PATTERN.matcher(fields[getYCol()]); if (x.matches() && y.matches() && x.groupCount() >= 4 && y.groupCount() >= 4) { return new LatLon(convertDegreeMinuteSecond(y), convertDegreeMinuteSecond(x)); } return null; } protected double convertDegreeMinuteSecond(Matcher m) { Double deg = Double.parseDouble(m.group(1)); Double min = Double.parseDouble(m.group(2)); Double sec = Double.parseDouble(m.group(3)); Double sign = deg < 0 || (m.groupCount() >= 5 && (m.group(4).equalsIgnoreCase("Sud") || m.group(4).equalsIgnoreCase("Ouest"))) ? -1.0 : +1.0; if (sign < 0) { if (deg > 0) { deg *= sign; } min *= sign; sec *= sign; } return OdUtils.convertDegreeMinuteSecond(deg, min, sec); } } }