Changeset 36294 in osm for applications/editors
- Timestamp:
- 2024-07-18T14:19:53+02:00 (4 months ago)
- Location:
- applications/editors/josm/plugins/SaudiNationalAddress
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/SaudiNationalAddress/build.xml
r35351 r36294 4 4 <!-- enter the SVN commit message --> 5 5 <property name="commit.message" value="Initial version."/> 6 <property name="plugin.main.version" value="1 0580"/>6 <property name="plugin.main.version" value="19044"/> 7 7 <property name="plugin.author" value="Mouath Ibrahim"/> 8 8 <property name="plugin.class" -
applications/editors/josm/plugins/SaudiNationalAddress/pom.xml
r36282 r36294 17 17 <properties> 18 18 <plugin.src.dir>src</plugin.src.dir> 19 <plugin.main.version>1 0580</plugin.main.version>19 <plugin.main.version>19044</plugin.main.version> 20 20 <plugin.author>Mouath Ibrahim</plugin.author> 21 21 <plugin.class>org.openstreetmap.josm.plugins.saudinationaladdress.SaudiNationalAddressPlugin</plugin.class> -
applications/editors/josm/plugins/SaudiNationalAddress/src/org/openstreetmap/josm/plugins/saudinationaladdress/SaudiNationalAddressAction.java
r35359 r36294 1 // License: GPL. For details, see LICENSE file. 1 2 package org.openstreetmap.josm.plugins.saudinationaladdress; 2 3 4 import jakarta.json.Json; 5 import jakarta.json.JsonArray; 6 import jakarta.json.JsonObject; 7 import jakarta.json.JsonReader; 3 8 import org.openstreetmap.josm.actions.JosmAction; 4 9 import org.openstreetmap.josm.command.ChangeCommand; … … 6 11 import org.openstreetmap.josm.command.SequenceCommand; 7 12 import org.openstreetmap.josm.data.UndoRedoHandler; 13 import org.openstreetmap.josm.data.coor.ILatLon; 8 14 import org.openstreetmap.josm.data.coor.LatLon; 9 15 import org.openstreetmap.josm.data.coor.conversion.DecimalDegreesCoordinateFormat; … … 17 23 import org.openstreetmap.josm.tools.HttpClient; 18 24 import org.openstreetmap.josm.tools.ImageProvider; 25 import org.openstreetmap.josm.tools.Logging; 19 26 import org.openstreetmap.josm.tools.Shortcut; 20 27 21 import javax.json.Json;22 import javax.json.JsonArray;23 import javax.json.JsonObject;24 import javax.json.JsonReader;25 import javax.swing.*;26 28 import java.awt.event.ActionEvent; 27 29 import java.awt.event.KeyEvent; 28 30 import java.io.BufferedReader; 29 31 import java.io.IOException; 30 import java.io.UnsupportedEncodingException;31 32 import java.net.MalformedURLException; 33 import java.net.URI; 34 import java.net.URISyntaxException; 32 35 import java.net.URL; 33 36 import java.net.URLEncoder; 37 import java.nio.charset.StandardCharsets; 34 38 import java.util.ArrayList; 35 39 import java.util.Collection; 36 40 import java.util.List; 37 41 42 import static org.openstreetmap.josm.tools.I18n.marktr; 38 43 import static org.openstreetmap.josm.tools.I18n.tr; 39 44 import static org.openstreetmap.josm.tools.I18n.trn; 40 45 46 import javax.swing.JOptionPane; 47 41 48 /** 42 * Created by tom on 02/08/15. (original y for AustriaAddressHelper plugin)43 * Mouath Ibrahim 05/03/2049 * Created by tom on 02/08/15. (originally for AustriaAddressHelper plugin) 50 * @author Mouath Ibrahim 05/03/20 44 51 */ 45 52 public class SaudiNationalAddressAction extends JosmAction { 46 53 static final String baseUrl = "https://apina.address.gov.sa/NationalAddress/v3.1/Address/address-geocode"; 47 54 private static final String GET_ADDRESS = marktr("Get Address"); 55 56 /** 57 * Create a new action for getting Saudi addresses 58 */ 48 59 public SaudiNationalAddressAction() { 49 super(tr( "Get Address"), new ImageProvider("icon.png"), tr("Get Address"),50 Shortcut.registerShortcut("Get Address", tr( "Get Address"),60 super(tr(GET_ADDRESS), new ImageProvider("icon.png"), tr(GET_ADDRESS), 61 Shortcut.registerShortcut("Get Address", tr(GET_ADDRESS), 51 62 KeyEvent.VK_G, Shortcut.CTRL), true, "getAddress", 52 63 true); 53 64 } 54 65 66 /** 67 * Load an address for an object 68 * @param selectedObject The object to get the address for 69 * @return The address if available, {@code null} otherwise 70 */ 55 71 public static OsmPrimitive loadAddress(OsmPrimitive selectedObject) { 56 final String API_KEY= Config.getPref().get(SaudiNationalAddressPreference.API_KEY);57 58 if (! API_KEY.isEmpty()) {72 final String apiKey = Config.getPref().get(SaudiNationalAddressPreference.API_KEY); 73 74 if (!apiKey.isEmpty()) { 59 75 LatLon center = selectedObject.getBBox().getCenter(); 60 76 // https://apina.address.gov.sa/NationalAddress/v3.1/Address/address-geocode?lat=25.36919&long=49.55076&language=E&format=json&encode=utf8 61 URL url = null; 62 try { 63 url = new URL(baseUrl 64 + "?lat=" + URLEncoder.encode(DecimalDegreesCoordinateFormat.INSTANCE.latToString(center), "UTF-8") 65 + "&long=" + URLEncoder.encode(DecimalDegreesCoordinateFormat.INSTANCE.lonToString(center), "UTF-8") 66 + "&language=A" // A for Arabic, E for English 67 + "&format=json" 68 + "&encode=utf8" 69 ); 70 } catch (MalformedURLException | UnsupportedEncodingException e) { 71 notification(e.getMessage(), JOptionPane.ERROR_MESSAGE); 72 } 73 74 JsonObject json = null; 75 try (BufferedReader in = HttpClient.create(url) 76 .setReasonForRequest("JOSM Plugin Saudi National Address") 77 .setHeader("api_key", API_KEY) 78 .connect() 79 .getContentReader(); 80 JsonReader reader = Json.createReader(in)) { 81 json = reader.readObject(); 82 } catch (IOException e) { 83 notification(e.getMessage(), JOptionPane.ERROR_MESSAGE); 84 85 } 86 77 URL url = generateUrl(center); 78 79 JsonObject json = getJson(apiKey, url); 87 80 // The api is not consistent in what it returns for error messages, hence this smart AI. 88 81 try { 89 82 if (json != null) { 90 83 if (json.containsKey("statusCode")) { 91 if ( !(json.getInt("statusCode") == 200)) {84 if (json.getInt("statusCode") != 200) { 92 85 notification(json.getString("message"), JOptionPane.ERROR_MESSAGE); // message: auth, rate limit errors 93 86 } … … 95 88 notification(tr("No address was found for this object."), JOptionPane.WARNING_MESSAGE); 96 89 } else { 97 final JsonArray addressItems = json.getJsonArray("Addresses"); 98 final JsonObject firstAddress = addressItems.getJsonObject(0); 99 100 String country = "SA"; 101 // String province = firstAddress.getString("RegionName"); 102 String district = firstAddress.getString("District"); 103 String postcode = firstAddress.getString("PostCode") + "-" + firstAddress.getString("AdditionalNumber"); 104 String city = firstAddress.getString("City"); 105 String buildingNumber = firstAddress.getString("BuildingNumber"); 106 String street = firstAddress.getString("Street"); 107 108 final OsmPrimitive newObject = selectedObject instanceof Node 109 ? new Node(((Node) selectedObject)) 110 : selectedObject instanceof Way 111 ? new Way((Way) selectedObject) 112 : selectedObject instanceof Relation 113 ? new Relation((Relation) selectedObject) 114 : null; 115 116 117 // seperate arabic and english 118 String[] districtArray = district.split(","); 119 String[] cityArray = city.split(","); 120 121 // newObject.put("addr:country", country); // can be determined from boundary relations 122 // newObject.put("addr:province", province); // can be determined from boundary relations 123 newObject.put("addr:postcode", postcode); 124 newObject.put("addr:city", cityArray[1]); 125 newObject.put("addr:city:en", cityArray[0]); 126 newObject.put("addr:district", districtArray[1]); // Arabic and common version 127 newObject.put("addr:district:en", districtArray[0]); 128 newObject.put("addr:housenumber", buildingNumber); 129 if (!street.isEmpty()) { 130 newObject.put("addr:street", street); 131 } // the api is still missing street names in some areas 132 133 String msg = tr("Successfully added address to selected object:") + "<br />" 134 + encodeHTML(street) + " " 135 + encodeHTML(buildingNumber) + ", " 136 + encodeHTML(postcode) + " " 137 + encodeHTML(district) + " (" 138 + encodeHTML(country) + ")<br/>"; 139 notification(msg, JOptionPane.INFORMATION_MESSAGE); 140 141 return newObject; 90 return createAddress(selectedObject, json); 142 91 } 143 92 } 144 93 } catch (NullPointerException e) { 94 Logging.error(e); 145 95 notification(tr("Unknown Error: ") + e.getMessage(), JOptionPane.ERROR_MESSAGE); 146 96 } 147 97 } else { 148 98 notification(tr("Please set your API key in the preference window!"), JOptionPane.ERROR_MESSAGE); 149 return null;150 99 } 151 100 return null; 152 101 } 153 102 103 private static URL generateUrl(ILatLon center) { 104 try { 105 return new URI(baseUrl 106 + "?lat=" + URLEncoder.encode(DecimalDegreesCoordinateFormat.INSTANCE.latToString(center), StandardCharsets.UTF_8) 107 + "&long=" + URLEncoder.encode(DecimalDegreesCoordinateFormat.INSTANCE.lonToString(center), StandardCharsets.UTF_8) 108 + "&language=A" // A for Arabic, E for English 109 + "&format=json" 110 + "&encode=utf8" 111 ).toURL(); 112 } catch (URISyntaxException | MalformedURLException e) { 113 Logging.trace(e); 114 notification(e.getMessage(), JOptionPane.ERROR_MESSAGE); 115 } 116 return null; 117 } 118 119 private static OsmPrimitive createAddress(OsmPrimitive selectedObject, JsonObject json) { 120 final JsonArray addressItems = json.getJsonArray("Addresses"); 121 final JsonObject firstAddress = addressItems.getJsonObject(0); 122 123 String country = "SA"; 124 // String province = firstAddress.getString("RegionName"); 125 String district = firstAddress.getString("District"); 126 String postcode = firstAddress.getString("PostCode") + "-" + firstAddress.getString("AdditionalNumber"); 127 String city = firstAddress.getString("City"); 128 String buildingNumber = firstAddress.getString("BuildingNumber"); 129 String street = firstAddress.getString("Street"); 130 131 final OsmPrimitive newObject = createPrimitive(selectedObject); 132 133 // separate arabic and english 134 String[] districtArray = district.split(","); 135 String[] cityArray = city.split(","); 136 137 // newObject.put("addr:country", country); // can be determined from boundary relations 138 // newObject.put("addr:province", province); // can be determined from boundary relations 139 newObject.put("addr:postcode", postcode); 140 newObject.put("addr:city", cityArray[1]); 141 newObject.put("addr:city:en", cityArray[0]); 142 newObject.put("addr:district", districtArray[1]); // Arabic and common version 143 newObject.put("addr:district:en", districtArray[0]); 144 newObject.put("addr:housenumber", buildingNumber); 145 if (!street.isEmpty()) { 146 newObject.put("addr:street", street); 147 } // the api is still missing street names in some areas 148 149 String msg = tr("Successfully added address to selected object:") + "<br />" 150 + encodeHTML(street) + " " 151 + encodeHTML(buildingNumber) + ", " 152 + encodeHTML(postcode) + " " 153 + encodeHTML(district) + " (" 154 + encodeHTML(country) + ")<br/>"; 155 notification(msg, JOptionPane.INFORMATION_MESSAGE); 156 157 return newObject; 158 } 159 160 private static JsonObject getJson(String apiKey, URL url) { 161 try (BufferedReader in = HttpClient.create(url) 162 .setReasonForRequest("JOSM Plugin Saudi National Address") 163 .setHeader("api_key", apiKey) 164 .connect() 165 .getContentReader(); 166 JsonReader reader = Json.createReader(in)) { 167 return reader.readObject(); 168 } catch (IOException e) { 169 Logging.trace(e); 170 notification(e.getMessage(), JOptionPane.ERROR_MESSAGE); 171 } 172 return null; 173 } 174 175 private static OsmPrimitive createPrimitive(OsmPrimitive selectedObject) { 176 if (selectedObject instanceof Node) { 177 return new Node((Node) selectedObject); 178 } 179 if (selectedObject instanceof Way) { 180 return new Way((Way) selectedObject); 181 } 182 if (selectedObject instanceof Relation) { 183 return new Relation((Relation) selectedObject); 184 } 185 throw new IllegalStateException("Unknown object type: " + selectedObject.getClass().getName()); 186 } 187 154 188 private static String encodeHTML(String s) { 155 StringBu ffer out = new StringBuffer();189 StringBuilder out = new StringBuilder(s.length()); 156 190 for (int i = 0; i < s.length(); i++) { 157 191 char c = s.charAt(i); 158 192 if (c > 127 || c == '"' || c == '<' || c == '>') { 159 out.append("&#" + (int) c + ";");193 out.append("&#").append((int) c).append(';'); 160 194 } else { 161 195 out.append(c);
Note:
See TracChangeset
for help on using the changeset viewer.