// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.administration;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.text.WordUtils;
import org.openstreetmap.josm.Main;
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.data.osm.OsmPrimitive;
import org.openstreetmap.josm.data.osm.Relation;
import org.openstreetmap.josm.data.osm.RelationMember;
import org.openstreetmap.josm.plugins.opendata.modules.fr.datagouvfr.datasets.DataGouvDataSetHandler;
import org.openstreetmap.josm.tools.Pair;
/**
* Handler for GeoFla 2.0. Compatibility for previous version 1.1 has been dropped.
* See http://professionnels.ign.fr/sites/default/files/DC_GEOFLA_2-0.pdf
*/
public class GeoFlaHandler extends DataGouvDataSetHandler {
private static final String ADMIN_LEVEL = "admin_level";
/**
* Constructs a new {@code GeoFlaHandler}.
*/
public GeoFlaHandler() {
setName("GEOFLA®");
getShpHandler().setPreferMultipolygonToSimpleWay(true);
try {
setLocalPortalURL("http://professionnels.ign.fr/geofla#tab-3");
} catch (MalformedURLException e) {
Main.error(e);
}
}
@Override
public String getLocalPortalIconName() {
return ICON_IGN_24;
}
@Override
public boolean acceptsFilename(String filename) {
return isDepartementFile(filename) || isCommuneFile(filename) || isCantonFile(filename) || isArrondissementFile(filename);
}
protected boolean isDepartementFile(String filename) {
return acceptsShpMifFilename(filename, "DEPARTEMENT") || acceptsShpMifFilename(filename, "LIMITE_DEPARTEMENT");
}
protected boolean isCommuneFile(String filename) {
return acceptsShpFilename(filename, "COMMUNE") || acceptsShpFilename(filename, "LIMITE_COMMUNE");
}
protected boolean isCantonFile(String filename) {
return acceptsShpFilename(filename, "CANTON") || acceptsShpFilename(filename, "LIMITE_CANTON");
}
protected boolean isArrondissementFile(String filename) {
return acceptsShpFilename(filename, "ARRONDISSEMENT") || acceptsShpFilename(filename, "LIMITE_ARRONDISSEMENT");
}
@Override
public void updateDataSet(DataSet ds) {
final String filename = getAssociatedFile().getName();
if (isDepartementFile(filename)) {
setNationalPortalPath("GEOFLA®-Départements-30383060");
} else if (isCommuneFile(filename)) {
setNationalPortalPath("GEOFLA®-Communes-30383083");
}
for (OsmPrimitive p : ds.allPrimitives()) {
if (hasKeyIgnoreCase(p, "Id_geofla", "Id_GéoFLA")) {
String deptName = WordUtils.capitalizeFully(getAndRemoveIgnoreCase(p, "Nom_dept", "Nom_Département"));
if ("Reunion".equals(deptName)) {
deptName = "La Réunion";
}
if (isDepartementFile(filename)) {
p.put("name", deptName);
} else if (isCommuneFile(filename)) {
p.put("name", WordUtils.capitalizeFully(getAndRemoveIgnoreCase(p, "NOM_COM")));
replace(p, "INSEE_COM", "ref:INSEE");
}
getAndRemoveIgnoreCase(p, "NOM_REG");
replace(p, "POPULATION", "population");
p.put("boundary", "administrative");
String nature = getIgnoreCase(p, "Nature");
if ("Frontière internationale".equalsIgnoreCase(nature) || "Limite côtière".equalsIgnoreCase(nature)) {
p.put(ADMIN_LEVEL, "2");
} else if ("Limite de région".equalsIgnoreCase(nature)) {
p.put(ADMIN_LEVEL, "4");
} else if (isDepartementFile(filename) || "Limite de département".equalsIgnoreCase(nature)) {
p.put(ADMIN_LEVEL, "6");
} else if(isArrondissementFile(filename) || "Limite d'arrondissement".equalsIgnoreCase(nature)) {
p.put(ADMIN_LEVEL, "7");
} else if(isCommuneFile(filename)) {
p.put(ADMIN_LEVEL, "8");
}
if (p instanceof Relation) {
p.put("type", "boundary");
}
LatLon llCentroid = getLatLon(p, deptName, "centroid", "Centroïde");
if (llCentroid != null) {
Node centroid = new Node(llCentroid);
ds.addPrimitive(centroid);
if (p instanceof Relation) {
((Relation) p).addMember(new RelationMember("centroid", centroid));
}
}
LatLon llChefLieu = getLatLon(p, deptName, "chf_lieu", "Chef_Lieu");
if (llChefLieu != null) {
Node chefLieu = new Node(llChefLieu);
ds.addPrimitive(chefLieu);
String name = WordUtils.capitalizeFully(getAndRemoveIgnoreCase(p, "Nom_chf", "Nom_Chef_lieu"));
if (name != null) {
if (isArrondissementFile(filename)) {
p.put("name", name);
}
chefLieu.put("name", name);
}
String population = p.get("population");
if (population != null) {
try {
int pop = Integer.parseInt(population);
if (pop < 2000) {
chefLieu.put("place", "village");
} else if (pop < 100000) {
chefLieu.put("place", "town");
} else {
chefLieu.put("place", "city");
}
} catch (NumberFormatException e) {
Main.warn("Invalid population: "+population);
}
}
if (p instanceof Relation) {
((Relation) p).addMember(new RelationMember("admin_centre", chefLieu));
}
}
}
}
}
protected static boolean hasKeyIgnoreCase(OsmPrimitive p, String ... strings) {
return getIgnoreCase(p, strings) != null;
}
protected static String getIgnoreCase(OsmPrimitive p, String ... strings) {
String result = null;
for (String s : strings) {
if (result == null) result = p.get(s);
if (result == null) result = p.get(s.toUpperCase());
if (result == null) result = p.get(s.toLowerCase());
}
return result;
}
protected static void removeIgnoreCase(OsmPrimitive p, String ... strings) {
for (String s : strings) {
p.remove(s);
p.remove(s.toUpperCase());
p.remove(s.toLowerCase());
}
}
protected static String getAndRemoveIgnoreCase(OsmPrimitive p, String ... strings) {
String result = getIgnoreCase(p, strings);
removeIgnoreCase(p, strings);
return result;
}
protected static LatLon getLatLon(OsmPrimitive p, String dptName, String shortAttribute, String longAttribute) {
String x = getAndRemoveIgnoreCase(p, "X_"+shortAttribute, "Abscisse_"+longAttribute);
String y = getAndRemoveIgnoreCase(p, "Y_"+shortAttribute, "Ordonnée_"+longAttribute);
if (x != null && y != null) {
try {
String dptCode = getIgnoreCase(p, "Code_dept", "Code_Département");
if (dptCode != null && dptCode.equals("97") && dptName != null) {
if (dptName.equals("Guadeloupe")) {
dptCode = "971";
} else if (dptName.equals("Martinique")) {
dptCode = "972";
} else if (dptName.equals("Guyane")) {
dptCode = "973";
} else if (dptName.equals("La Réunion")) {
dptCode = "974";
} else if (dptName.equals("Mayotte")) {
dptCode = "976";
} else {
Main.error("Unknown French department: "+dptName);
}
}
return getLatLonByDptCode(new EastNorth(Double.parseDouble(x), Double.parseDouble(y)), dptCode, false);
} catch (NumberFormatException e) {
Main.error(e);
}
}
return null;
}
private Pair<String, URL> getGeoflaURL(String name, String urlSuffix) throws MalformedURLException {
return new Pair<>(name, new URL("https://wxs-telechargement.ign.fr/oikr5jryiph0iwhw36053ptm/telechargement/inspire/"+urlSuffix));
}
@Override
public List<Pair<String, URL>> getDataURLs() {
List<Pair<String, URL>> result = new ArrayList<>();
try {
// Communes
result.add(getGeoflaURL("2014 Communes France Métropolitaine", "GEOFLA_THEME-COMMUNE_2014_GEOFLA_2-0_COMMUNE_SHP_LAMB93_FXX_2014-12-05/file/GEOFLA_2-0_COMMUNE_SHP_LAMB93_FXX_2014-12-05.7z"));
result.add(getGeoflaURL("2014 Communes Guadeloupe", "GEOFLA_THEME-COMMUNE_2014_GEOFLA_2-0_COMMUNE_SHP_UTM20W84GUAD_D971_2014-12-08/file/GEOFLA_2-0_COMMUNE_SHP_UTM20W84GUAD_D971_2014-12-08.7z"));
result.add(getGeoflaURL("2014 Communes Martinique", "GEOFLA_THEME-COMMUNE_2014_GEOFLA_2-0_COMMUNE_SHP_UTM20W84MART_D972_2014-12-08/file/GEOFLA_2-0_COMMUNE_SHP_UTM20W84MART_D972_2014-12-08.7z"));
result.add(getGeoflaURL("2014 Communes Guyane", "GEOFLA_THEME-COMMUNE_2014_GEOFLA_2-0_COMMUNE_SHP_UTM22RGFG95_D973_2014-12-05/file/GEOFLA_2-0_COMMUNE_SHP_UTM22RGFG95_D973_2014-12-05.7z"));
result.add(getGeoflaURL("2014 Communes Réunion", "GEOFLA_THEME-COMMUNE_2014_GEOFLA_2-0_COMMUNE_SHP_RGR92UTM40S_D974_2014-12-05/file/GEOFLA_2-0_COMMUNE_SHP_RGR92UTM40S_D974_2014-12-05.7z"));
result.add(getGeoflaURL("2014 Communes Mayotte", "GEOFLA_THEME-COMMUNE_2014_GEOFLA_2-0_COMMUNE_SHP_RGM04UTM38S_D976_2014-12-05/file/GEOFLA_2-0_COMMUNE_SHP_RGM04UTM38S_D976_2014-12-05.7z"));
// Cantons
result.add(getGeoflaURL("2014 Cantons France Métropolitaine", "GEOFLA_THEME-CANTON_2014_GEOFLA_2-0_CANTON_SHP_LAMB93_FXX_2014-12-05/file/GEOFLA_2-0_CANTON_SHP_LAMB93_FXX_2014-12-05.7z"));
result.add(getGeoflaURL("2014 Cantons Guadeloupe", "GEOFLA_THEME-CANTON_2014_GEOFLA_2-0_CANTON_SHP_UTM20W84GUAD_D971_2014-12-08/file/GEOFLA_2-0_CANTON_SHP_UTM20W84GUAD_D971_2014-12-08.7z"));
result.add(getGeoflaURL("2014 Cantons Martinique", "GEOFLA_THEME-CANTON_2014_GEOFLA_2-0_CANTON_SHP_UTM20W84MART_D972_2014-12-08/file/GEOFLA_2-0_CANTON_SHP_UTM20W84MART_D972_2014-12-08.7z"));
result.add(getGeoflaURL("2014 Cantons Guyane", "GEOFLA_THEME-CANTON_2014_GEOFLA_2-0_CANTON_SHP_UTM22RGFG95_D973_2014-12-05/file/GEOFLA_2-0_CANTON_SHP_UTM22RGFG95_D973_2014-12-05.7z"));
result.add(getGeoflaURL("2014 Cantons Réunion", "GEOFLA_THEME-CANTON_2014_GEOFLA_2-0_CANTON_SHP_RGR92UTM40S_D974_2014-12-05/file/GEOFLA_2-0_CANTON_SHP_RGR92UTM40S_D974_2014-12-05.7z"));
result.add(getGeoflaURL("2014 Cantons Mayotte", "GEOFLA_THEME-CANTON_2014_GEOFLA_2-0_CANTON_SHP_RGM04UTM38S_D976_2014-12-05/file/GEOFLA_2-0_CANTON_SHP_RGM04UTM38S_D976_2014-12-05.7z"));
// Arrondissements
result.add(getGeoflaURL("2014 Arrondissements France Métropolitaine", "GEOFLA_THEME-ARRONDISSEMENT_2014_GEOFLA_2-0_ARRONDISSEMENT_SHP_LAMB93_FXX_2014-12-05/file/GEOFLA_2-0_ARRONDISSEMENT_SHP_LAMB93_FXX_2014-12-05.7z"));
result.add(getGeoflaURL("2014 Arrondissements Guadeloupe", "GEOFLA_THEME-ARRONDISSEMENT_2014_GEOFLA_2-0_ARRONDISSEMENT_SHP_UTM20W84GUAD_D971_2014-12-08/file/GEOFLA_2-0_ARRONDISSEMENT_SHP_UTM20W84GUAD_D971_2014-12-08.7z"));
result.add(getGeoflaURL("2014 Arrondissements Martinique", "GEOFLA_THEME-ARRONDISSEMENT_2014_GEOFLA_2-0_ARRONDISSEMENT_SHP_UTM20W84MART_D972_2014-12-08/file/GEOFLA_2-0_ARRONDISSEMENT_SHP_UTM20W84MART_D972_2014-12-08.7z"));
result.add(getGeoflaURL("2014 Arrondissements Guyane", "GEOFLA_THEME-ARRONDISSEMENT_2014_GEOFLA_2-0_ARRONDISSEMENT_SHP_UTM22RGFG95_D973_2014-12-05/file/GEOFLA_2-0_ARRONDISSEMENT_SHP_UTM22RGFG95_D973_2014-12-05.7z"));
result.add(getGeoflaURL("2014 Arrondissements Réunion", "GEOFLA_THEME-ARRONDISSEMENT_2014_GEOFLA_2-0_ARRONDISSEMENT_SHP_RGR92UTM40S_D974_2014-12-05/file/GEOFLA_2-0_ARRONDISSEMENT_SHP_RGR92UTM40S_D974_2014-12-05.7z"));
// Départements
result.add(getGeoflaURL("2014 Départements France Métropolitaine", "GEOFLA_THEME-DEPARTEMENTS_2014_GEOFLA_2-0_DEPARTEMENT_SHP_LAMB93_FXX_2014-12-05/file/GEOFLA_2-0_DEPARTEMENT_SHP_LAMB93_FXX_2014-12-05.7z"));
result.add(getGeoflaURL("2014 Départements Guadeloupe", "GEOFLA_THEME-DEPARTEMENTS_2014_GEOFLA_2-0_DEPARTEMENT_SHP_UTM20W84GUAD_D971_2014-12-08/file/GEOFLA_2-0_DEPARTEMENT_SHP_UTM20W84GUAD_D971_2014-12-08.7z"));
result.add(getGeoflaURL("2014 Départements Martinique", "GEOFLA_THEME-DEPARTEMENTS_2014_GEOFLA_2-0_DEPARTEMENT_SHP_UTM20W84MART_D972_2014-12-08/file/GEOFLA_2-0_DEPARTEMENT_SHP_UTM20W84MART_D972_2014-12-08.7z"));
result.add(getGeoflaURL("2014 Départements Guyane", "GEOFLA_THEME-DEPARTEMENTS_2014_GEOFLA_2-0_DEPARTEMENT_SHP_UTM22RGFG95_D973_2014-12-05/file/GEOFLA_2-0_DEPARTEMENT_SHP_UTM22RGFG95_D973_2014-12-05.7z"));
result.add(getGeoflaURL("2014 Départements Réunion", "GEOFLA_THEME-DEPARTEMENTS_2014_GEOFLA_2-0_DEPARTEMENT_SHP_RGR92UTM40S_D974_2014-12-05/file/GEOFLA_2-0_DEPARTEMENT_SHP_RGR92UTM40S_D974_2014-12-05.7z"));
result.add(getGeoflaURL("2014 Départements Mayotte", "GEOFLA_THEME-DEPARTEMENTS_2014_GEOFLA_2-0_DEPARTEMENT_SHP_RGM04UTM38S_D976_2014-12-05/file/GEOFLA_2-0_DEPARTEMENT_SHP_RGM04UTM38S_D976_2014-12-05.7z"));
} catch (MalformedURLException e) {
Main.error(e);
}
return result;
}
}