source: osm/applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/CadastreInterface.java@ 13417

Last change on this file since 13417 was 13382, checked in by pieren, 16 years ago

First commit of the french land registry WMS plugin for JOSM.

File size: 15.0 KB
Line 
1package cadastre_fr;
2
3import static org.openstreetmap.josm.tools.I18n.tr;
4
5import java.awt.GridBagLayout;
6import java.io.BufferedReader;
7import java.io.IOException;
8import java.io.InputStreamReader;
9import java.io.OutputStream;
10import java.net.HttpURLConnection;
11import java.net.MalformedURLException;
12import java.net.URL;
13import java.util.Vector;
14
15import javax.swing.JComboBox;
16import javax.swing.JOptionPane;
17import javax.swing.JPanel;
18
19import org.openstreetmap.josm.Main;
20import org.openstreetmap.josm.gui.layer.Layer;
21import org.openstreetmap.josm.tools.GBC;
22
23public class CadastreInterface {
24 public boolean downloadCancelled = false;
25 public HttpURLConnection urlConn = null;
26
27 private CadastreGrabber cadastreGrabber;
28 private String cookie;
29 private String interfaceRef = null;
30 private URL searchFormURL;
31 private Vector<String> listOfCommunes = new Vector<String>();
32 private Vector<String> listOfTA = new Vector<String>();
33
34 final String baseURL = "http://www.cadastre.gouv.fr";
35 final String cImageFormat = "Cette commune est au format ";
36 final String cCommuneListStart = "<select name=\"codeCommune\"";
37 final String cCommuneListEnd = "</select>";
38 final String c0ptionListStart = "<option value=\"";
39 final String cOptionListEnd = "</option>";
40
41 final String cInterfaceVector = "afficherCarteCommune.do";
42 final String cInterfaceRaster = "afficherCarteTa.do";
43
44 CadastreInterface(CadastreGrabber cadastreGrabber) {
45 this.cadastreGrabber = cadastreGrabber;
46 }
47
48 public boolean retrieveInterface(WMSLayer wmsLayer) throws DuplicateLayerException {
49 if (wmsLayer.name.equals(""))
50 return false;
51 // open the session with the french Cadastre web front end
52 downloadCancelled = false;
53 try {
54 if (cookie == null || !wmsLayer.name.equals(cadastreGrabber.getLastWMSLayerName())) {
55 getCookie();
56 getInterface(wmsLayer);
57 cadastreGrabber.setLastWMSLayerName(wmsLayer.name);
58 }
59 openInterface();
60 } catch (IOException e) {
61 e.printStackTrace();
62 return false;
63 }
64 return true;
65 }
66
67 private void getCookie() throws IOException {
68 try {
69 // first, get the cookie from Cadastre to allow next downloads
70 searchFormURL = new URL(baseURL + "/scpc/rechercherPlan.do");
71 urlConn = (HttpURLConnection)searchFormURL.openConnection();
72 urlConn.setRequestMethod("GET");
73 urlConn.connect();
74 if (urlConn.getResponseCode() != HttpURLConnection.HTTP_OK) {
75 throw (IOException) new IOException("Cannot get Cadastre cookie.");
76 }
77 BufferedReader in = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
78 while(in.readLine() != null) {} // read the buffer otherwise we sent POST too early
79 String headerName=null;
80 for (int i=1; (headerName = urlConn.getHeaderFieldKey(i))!=null; i++) {
81 if (headerName.equals("Set-Cookie")) {
82 cookie = urlConn.getHeaderField(i);
83 cookie = cookie.substring(0, cookie.indexOf(";"));
84 System.out.println("Cookie="+cookie);
85 }
86 }
87 } catch (MalformedURLException e) {
88 throw (IOException) new IOException(
89 "Illegal url.").initCause(e);
90 }
91 }
92
93 public void resetCookie() {
94 cadastreGrabber.setLastWMSLayerName(null);
95 }
96
97 public void resetCookieIfNewLayer(String newWMSLayerName) {
98 if (!newWMSLayerName.equals(cadastreGrabber.getLastWMSLayerName())) {
99 resetCookie();
100 }
101 }
102
103 public void setCookie() {
104 urlConn.setRequestProperty("Cookie", cookie);
105 }
106
107 private void getInterface(WMSLayer wmsLayer) throws IOException, DuplicateLayerException {
108 // first attempt : search for given name without codeCommune
109 interfaceRef = postForm(wmsLayer, "");
110 // second attempt either from known codeCommune (e.g. from cache) or from ComboBox
111 if (interfaceRef == null) {
112 if (!wmsLayer.getCodeCommune().equals("")) {
113 // codeCommune is already known (from previous request or from cache on disk)
114 interfaceRef = postForm(wmsLayer, wmsLayer.getCodeCommune());
115 } else {
116 if (listOfCommunes.size() > 1) {
117 // commune unknown, prompt the list of communes from
118 // server and try with codeCommune
119 wmsLayer.setCodeCommune(selectCommuneDialog());
120 checkLayerDuplicates(wmsLayer);
121 interfaceRef = postForm(wmsLayer, wmsLayer.getCodeCommune());
122 }
123 if (wmsLayer.isRaster() && listOfTA.size() > 1) {
124 // commune known but raster format. Select "tableau d'assemblage" from list.
125 wmsLayer.setCodeCommune(selectTADialog());
126 checkLayerDuplicates(wmsLayer);
127 interfaceRef = buildRasterInterfaceRef(wmsLayer.getCodeCommune());
128 }
129 }
130 }
131
132 if (interfaceRef == null)
133 throw new IOException("Town/city " + wmsLayer.getLocation() + " not found.");
134 }
135
136 private void openInterface() throws IOException {
137 try {
138 // finally, open the interface on server side giving access to the wms server
139 URL interfaceURL = new URL(baseURL + "/scpc/"+interfaceRef);
140 urlConn = (HttpURLConnection)interfaceURL.openConnection();
141 urlConn.setRequestMethod("GET");
142 setCookie();
143 urlConn.connect();
144 if (urlConn.getResponseCode() != HttpURLConnection.HTTP_OK) {
145 throw (IOException) new IOException("Cannot open Cadastre interface. GET response:"+urlConn.getResponseCode());
146 }
147 BufferedReader in = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
148 while(in.readLine() != null) {} // read the buffer otherwise we sent POST too early
149 System.out.println("GET to open interface sent");
150 } catch (MalformedURLException e) {
151 throw (IOException) new IOException(
152 "CadastreGrabber: Illegal url.").initCause(e);
153 }
154 }
155
156 /**
157 * Post the form with the commune name and check the returned answer which is embedded
158 * in HTTP XML packets. This function doesn't use an XML parser yet but that would be a good idea
159 * for the next releases.
160 * Two possibilities :
161 * - either the commune name matches and we receive an URL starting with "afficherCarteCommune.do" or
162 * - we don't receive a single answer but a list of possible values. This answer looks like:
163 * <select name="codeCommune" class="long erreur" id="codeCommune">
164 * <option value="">Choisir</option>
165 * <option value="50061" >COLMARS - 04370</option>
166 * <option value="QK066" >COLMAR - 68000</option>
167 * </select>
168 *
169 * @param location
170 * @param codeCommune
171 * @return retURL url to available cadastre vectorised master piece; "" if not found
172 * @throws IOException
173 */
174 private String postForm(WMSLayer wmsLayer, String codeCommune) throws IOException {
175 try {
176 String ln = null;
177 String line = null;
178 listOfCommunes.clear();
179 listOfTA.clear();
180 // send a POST request with a city/town/village name
181 String content = "numerovoie=";
182 content += "&indiceRepetition=";
183 content += "&nomvoie=";
184 content += "&lieuDit=";
185 if (codeCommune == "") {
186 content += "&ville=" + new String(java.net.URLEncoder.encode(wmsLayer.getLocation(), "UTF-8"));
187 content += "&codePostal=";
188 } else {
189 content += "&codeCommune=" + codeCommune;
190 }
191 content += "&codeDepartement=";
192 content += "&nbResultatParPage=10";
193 urlConn = (HttpURLConnection)searchFormURL.openConnection();
194 urlConn.setRequestMethod("POST");
195 urlConn.setDoOutput(true);
196 urlConn.setDoInput(true);
197 setCookie();
198 OutputStream wr = urlConn.getOutputStream();
199 wr.write(content.getBytes());
200 wr.flush();
201 wr.close();
202 BufferedReader rd = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
203 while ((ln = rd.readLine()) != null) {
204 line += ln;
205 }
206 rd.close();
207 urlConn.disconnect();
208 System.out.println("POST="+line);
209 if (line.indexOf(cImageFormat) != -1) {
210 int i = line.indexOf(cImageFormat);
211 int j = line.indexOf(".", i);
212 wmsLayer.setRaster(line.substring(i+cImageFormat.length(), j).equals("image"));
213 }
214 if (!wmsLayer.isRaster() && line.indexOf(cInterfaceVector) != -1) { // "afficherCarteCommune.do"
215 // shall be something like: interfaceRef = "afficherCarteCommune.do?c=X2269";
216 line = line.substring(line.indexOf(cInterfaceVector),line.length());
217 line = line.substring(0, line.indexOf("'"));
218 System.out.println("interface ref.:"+line);
219 return line;
220 } else if (wmsLayer.isRaster() && line.indexOf(cInterfaceRaster) != -1) { // "afficherCarteTa.do"
221 // list of values parsed in listOfTA (Tableau d'assemblage)
222 parseTAList(line.substring(line.indexOf(cInterfaceRaster)));
223 if (listOfTA.size() == 1) {
224 wmsLayer.setCodeCommune(listOfTA.firstElement());
225 return buildRasterInterfaceRef(listOfTA.firstElement());
226 }
227 return null;
228 } else if (line.indexOf(cCommuneListStart) != -1 && line.indexOf(cCommuneListEnd) != -1) {
229 // list of values parsed in listOfCommunes
230 int i = line.indexOf(cCommuneListStart);
231 int j = line.indexOf(cCommuneListEnd, i);
232 parseCommuneList(line.substring(i, j));
233 }
234 } catch (MalformedURLException e) {
235 throw (IOException) new IOException(
236 "Illegal url.").initCause(e);
237 } catch (Exception e){
238 e.printStackTrace();
239 }
240 return null;
241 }
242
243 private void parseCommuneList(String input) {
244 if (input.indexOf(c0ptionListStart) != -1) {
245 while (input.indexOf("<option value=\"") != -1) {
246 int i = input.indexOf(c0ptionListStart);
247 int j = input.indexOf(cOptionListEnd, i+c0ptionListStart.length());
248 int k = input.indexOf("\"", i+c0ptionListStart.length());
249 if (j != -1 && k > (i + c0ptionListStart.length())) {
250 String lov = new String(input.substring(i+c0ptionListStart.length()-1, j));
251 if (lov.indexOf(">") != -1) {
252 System.out.println("parse "+lov);
253 listOfCommunes.add(lov);
254 } else
255 System.err.println("unable to parse commune string:"+lov);
256 }
257 input = input.substring(j+cOptionListEnd.length());
258 }
259 }
260 }
261
262 private void parseTAList(String input) {
263 while (input.indexOf(cInterfaceRaster) != -1) {
264 input = input.substring(input.indexOf(cInterfaceRaster));
265 String codeTA = input.substring(0, input.indexOf("'"));
266 codeTA = codeTA.substring(codeTA.indexOf("=")+1);
267 if (!listOfTA.contains(codeTA)) {
268 System.out.println("parse "+codeTA);
269 listOfTA.add(codeTA);
270 }
271 input = input.substring(cInterfaceRaster.length());
272 }
273 }
274
275 private String selectCommuneDialog() {
276 JPanel p = new JPanel(new GridBagLayout());
277 String[] communeList = new String[listOfCommunes.size() + 1];
278 communeList[0] = tr("Choose from...");
279 for (int i = 0; i < listOfCommunes.size(); i++) {
280 communeList[i + 1] = listOfCommunes.elementAt(i).substring(listOfCommunes.elementAt(i).indexOf(">")+1);
281 }
282 JComboBox inputCommuneList = new JComboBox(communeList);
283 p.add(inputCommuneList, GBC.eol().fill(GBC.HORIZONTAL).insets(10, 0, 0, 0));
284 JOptionPane pane = new JOptionPane(p, JOptionPane.INFORMATION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null) {
285 private static final long serialVersionUID = 1L;
286 };
287 pane.createDialog(Main.parent, tr("Select commune")).setVisible(true);
288 if (!Integer.valueOf(JOptionPane.OK_OPTION).equals(pane.getValue()))
289 return null;
290 String result = listOfCommunes.elementAt(inputCommuneList.getSelectedIndex()-1);
291 return result.substring(1, result.indexOf(">")-2);
292 }
293
294 private String selectTADialog() {
295 JPanel p = new JPanel(new GridBagLayout());
296 JComboBox inputTAList = new JComboBox(listOfTA);
297 p.add(inputTAList, GBC.eol().fill(GBC.HORIZONTAL).insets(10, 0, 0, 0));
298 JOptionPane pane = new JOptionPane(p, JOptionPane.INFORMATION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null) {
299 private static final long serialVersionUID = 1L;
300 };
301 pane.createDialog(Main.parent, tr("Select Tableau d'Assemblage")).setVisible(true);
302 if (!Integer.valueOf(JOptionPane.OK_OPTION).equals(pane.getValue()))
303 return null;
304 String result = listOfTA.elementAt(inputTAList.getSelectedIndex());
305 return result;
306 }
307
308 private String buildRasterInterfaceRef(String codeCommune) {
309 return cInterfaceRaster + "?f=" + codeCommune;
310 }
311
312 private void checkLayerDuplicates(WMSLayer wmsLayer) throws DuplicateLayerException {
313 if (Main.map != null) {
314 for (Layer l : Main.map.mapView.getAllLayers()) {
315 if (l instanceof WMSLayer && l.name.equals(wmsLayer.name) && (l != wmsLayer)) {
316 System.out.println("Try to grab into a new layer when "+wmsLayer.name+" is already opened.");
317 // remove the duplicated layer
318 Main.map.mapView.removeLayer(wmsLayer);
319 throw new DuplicateLayerException();
320 }
321 }
322 }
323 }
324
325 public void cancel() {
326 Main.pleaseWaitDlg.currentAction.setText(tr("Aborting..."));
327 if (urlConn != null) {
328 urlConn.setConnectTimeout(1);
329 urlConn.setReadTimeout(1);
330 //urlConn.disconnect();
331 }
332 downloadCancelled = true;
333 cadastreGrabber.setLastWMSLayerName(null);
334 }
335
336}
Note: See TracBrowser for help on using the repository browser.