// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.opendata.core.datasets.fr;
import static org.openstreetmap.josm.plugins.opendata.core.io.LambertCC9ZonesProjectionPatterns.lambertCC9Zones;
import java.net.MalformedURLException;
import java.net.URL;
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.OsmPrimitive;
import org.openstreetmap.josm.data.osm.Tag;
import org.openstreetmap.josm.data.projection.Projection;
import org.openstreetmap.josm.data.projection.Projections;
import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
import org.openstreetmap.josm.plugins.opendata.core.datasets.SimpleDataSetHandler;
import org.openstreetmap.josm.plugins.opendata.core.io.tabular.DefaultCsvHandler;
public abstract class FrenchDataSetHandler extends SimpleDataSetHandler implements FrenchConstants {
private Projection singleProjection;
private String nationalPortalPath;
protected static final Projection lambert93 = OdConstants.PRJ_LAMBERT_93.getProjection(); // France metropolitaine
protected static final Projection utm20 = Projections.getProjectionByCode("EPSG:32620"); // UTM 20 N - Guadeloupe, Martinique
protected static final Projection utm22 = Projections.getProjectionByCode("EPSG:32622"); // UTM 22 N - Guyane
protected static final Projection utm38 = Projections.getProjectionByCode("EPSG:32738"); // UTM 38 S - Mayotte
protected static final Projection utm40 = Projections.getProjectionByCode("EPSG:32740"); // UTM 40 S - Reunion
protected static final Projection[] lambert4Zones = new Projection[4];
static {
for (int i = 0; i < lambert4Zones.length; i++) {
lambert4Zones[i] = Projections.getProjectionByCode("EPSG:"+Integer.toString(27561+i));
}
}
protected static final Projection[] projections = new Projection[]{
lambert93, // France metropolitaine
utm20, // Guadeloupe, Martinique
utm22, // Guyane
utm38, // Mayotte
utm40, // Reunion
};
protected class InternalCsvHandler extends DefaultCsvHandler {
/*@Override
public List<Projection> getSpreadSheetProjections() {
if (singleProjection != null) {
return Arrays.asList(new Projection[]{singleProjection});
} else {
return Arrays.asList(projections);
}
}*/
@Override
public LatLon getCoor(EastNorth en, String[] fields) {
if (singleProjection != null) {
return singleProjection.eastNorth2latlon(en);
} else {
return super.getCoor(en, fields);
}
}
@Override
public boolean handlesProjection() {
return singleProjection != null;
}
}
public FrenchDataSetHandler() {
init();
}
public FrenchDataSetHandler(String relevantTag) {
super(relevantTag);
init();
}
public FrenchDataSetHandler(boolean relevantUnion, String[] relevantTags) {
super(relevantUnion, relevantTags);
init();
}
public FrenchDataSetHandler(boolean relevantUnion, Tag[] relevantTags) {
super(relevantUnion, relevantTags);
init();
}
private void init() {
setShpHandler(new FrenchShpHandler());
setCsvHandler(new InternalCsvHandler());
}
protected final void setNationalPortalPath(String nationalPortalPath) {
this.nationalPortalPath = nationalPortalPath;
}
protected final void setSingleProjection(Projection singleProjection) {
this.singleProjection = singleProjection;
}
@Override
public URL getNationalPortalURL() {
try {
if (nationalPortalPath != null && !nationalPortalPath.isEmpty()) {
return new URL(FRENCH_PORTAL + "donnees/view/" + nationalPortalPath);
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
@Override
public String getLocalPortalIconName() {
return ICON_FR_24;
}
@Override
public String getNationalPortalIconName() {
return ICON_FR_24;
}
protected static final LatLon getLatLonByDptCode(EastNorth en, String dpt, boolean useCC9) {
// CHECKSTYLE.OFF: LineLength
if (dpt.equals("971") || dpt.equals("972") || dpt.equals("977") || dpt.equals("978")) { // Antilles
return utm20.eastNorth2latlon(en);
} else if (dpt.equals("973")) { // Guyane
return utm22.eastNorth2latlon(en);
} else if (dpt.equals("974")) { // La Réunion
return utm40.eastNorth2latlon(en);
} else if (dpt.equals("976") || dpt.equals("985")) { // 985 = ancien code de Mayotte ? (présent dans geofla)
return utm38.eastNorth2latlon(en);
} else if (!useCC9) {
return lambert93.eastNorth2latlon(en);
} else if (dpt.endsWith("2A") || dpt.endsWith("2B") || dpt.endsWith("20")) {
return lambertCC9Zones[0].eastNorth2latlon(en);
} else if (dpt.endsWith("64") || dpt.endsWith("65") || dpt.endsWith("31") || dpt.endsWith("09") || dpt.endsWith("11") || dpt.endsWith("66") || dpt.endsWith("34") || dpt.endsWith("83")) {
return lambertCC9Zones[1].eastNorth2latlon(en);
} else if (dpt.endsWith("40") || dpt.endsWith("32") || dpt.endsWith("47") || dpt.endsWith("82") || dpt.endsWith("81") || dpt.endsWith("12") || dpt.endsWith("48") || dpt.endsWith("30") || dpt.endsWith("13") || dpt.endsWith("84") || dpt.endsWith("04") || dpt.endsWith("06")) {
return lambertCC9Zones[2].eastNorth2latlon(en);
} else if (dpt.endsWith("33") || dpt.endsWith("24") || dpt.endsWith("46") || dpt.endsWith("19") || dpt.endsWith("15") || dpt.endsWith("43") || dpt.endsWith("07") || dpt.endsWith("26") || dpt.endsWith("05") || dpt.endsWith("38") || dpt.endsWith("73")) {
return lambertCC9Zones[3].eastNorth2latlon(en);
} else if (dpt.endsWith("17") || dpt.endsWith("16") || dpt.endsWith("87") || dpt.endsWith("23") || dpt.endsWith("63") || dpt.endsWith("03") || dpt.endsWith("42") || dpt.endsWith("69") || dpt.endsWith("01") || dpt.endsWith("74")) {
return lambertCC9Zones[4].eastNorth2latlon(en);
} else if (dpt.endsWith("44") || dpt.endsWith("85") || dpt.endsWith("49") || dpt.endsWith("79") || dpt.endsWith("37") || dpt.endsWith("86") || dpt.endsWith("36") || dpt.endsWith("18") || dpt.endsWith("58") || dpt.endsWith("71") || dpt.endsWith("21") || dpt.endsWith("39") || dpt.endsWith("25")) {
return lambertCC9Zones[5].eastNorth2latlon(en);
} else if (dpt.endsWith("29") || dpt.endsWith("56") || dpt.endsWith("22") || dpt.endsWith("35") || dpt.endsWith("53") || dpt.endsWith("72") || dpt.endsWith("41") || dpt.endsWith("28") || dpt.endsWith("45") || dpt.endsWith("89") || dpt.endsWith("10") || dpt.endsWith("52") || dpt.endsWith("70") || dpt.endsWith("88") || dpt.endsWith("68") || dpt.endsWith("90")) {
return lambertCC9Zones[6].eastNorth2latlon(en);
} else if (dpt.endsWith("50") || dpt.endsWith("14") || dpt.endsWith("61") || dpt.endsWith("27") || dpt.endsWith("60") || dpt.endsWith("95") || dpt.endsWith("78") || dpt.endsWith("91") || dpt.endsWith("92") || dpt.endsWith("93") || dpt.endsWith("94") || dpt.endsWith("75") || dpt.endsWith("77") || dpt.endsWith("60") || dpt.endsWith("02") || dpt.endsWith("51") || dpt.endsWith("55") || dpt.endsWith("54") || dpt.endsWith("57") || dpt.endsWith("67")) {
return lambertCC9Zones[7].eastNorth2latlon(en);
} else if (dpt.endsWith("76") || dpt.endsWith("80") || dpt.endsWith("62") || dpt.endsWith("59") || dpt.endsWith("08")) {
return lambertCC9Zones[8].eastNorth2latlon(en);
} else {
throw new IllegalArgumentException("Unsupported department code: "+dpt);
}
// CHECKSTYLE.ON: LineLength
}
private void replaceFaxPhone(OsmPrimitive p, String dataKey, String osmKey) {
String phone = p.get(dataKey);
if (phone != null) {
p.put(osmKey, phone.replace(" ", "").replace(".", "").replaceFirst("0", "+33"));
p.remove(dataKey);
}
}
protected void replaceFax(OsmPrimitive p, String dataKey) {
replaceFaxPhone(p, dataKey, "contact:fax");
}
protected void replacePhone(OsmPrimitive p, String dataKey) {
replaceFaxPhone(p, dataKey, "contact:phone");
}
private static final String dayFr = "L|Lu|M|Ma|Me|J|Je|V|Ve|S|Sa|D|Di";
private static final String dayEn = "Mo|Mo|Tu|Tu|We|Th|Th|Fr|Fr|Sa|Sa|Su|Su";
private static final String[] dayFrSplit = dayFr.split("\\|");
private static final String[] dayEnSplit = dayEn.split("\\|");
protected void replaceOpeningHours(OsmPrimitive p, String dataKey) {
String hours = p.get(dataKey);
if (hours != null) {
hours = hours.replace("h", ":").replace(": ", ":00 ");
hours = hours.replace(" - ", "-").replace(" au ", "-").replace(" à ", "-");
hours = hours.replace(" et ", ",").replace("/", ",");
hours = hours.replace(" (sf vacances)", "; PH off");
if (hours.endsWith(":")) {
hours += "00";
}
String dayGroup = "("+dayFr+")";
String dayNcGroup = "(?:"+dayFr+")";
// FIXME: this doesn't work yet
for (String sep : new String[]{"-", ","}) {
boolean finished = false;
while (!finished) {
Matcher m = Pattern.compile(".*("+dayNcGroup+"(?:"+sep+dayNcGroup+")+).*").matcher(hours);
if (m.matches()) {
String range = m.group(1);
Matcher m2 = Pattern.compile(dayGroup+"(?:"+sep+dayGroup+")+").matcher(range);
if (m2.matches()) {
String replacement = "";
for (int i = 0; i < m2.groupCount(); i++) {
if (i > 0) {
replacement += sep;
}
replacement += getEnDay(m2.group(i+1));
}
hours = hours.replace(range, replacement);
}
} else {
finished = true;
}
}
}
p.put("opening_hours", hours);
p.remove(dataKey);
}
}
private String getEnDay(String frDay) {
for (int i = 0; i < dayFrSplit.length; i++) {
if (dayFrSplit[i].equals(frDay)) {
return dayEnSplit[i];
}
}
return "";
}
}