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

Last change on this file since 13727 was 13611, checked in by pieren, 16 years ago

Fix minor issues.

File size: 9.1 KB
Line 
1package cadastre_fr;
2
3import static org.openstreetmap.josm.tools.I18n.tr;
4
5import java.io.BufferedOutputStream;
6import java.io.BufferedReader;
7import java.io.File;
8import java.io.FileOutputStream;
9import java.io.IOException;
10import java.io.InputStream;
11import java.io.InputStreamReader;
12import java.net.HttpURLConnection;
13import java.net.MalformedURLException;
14import java.net.URL;
15import java.util.ArrayList;
16import java.util.Collection;
17import java.util.LinkedList;
18import java.util.List;
19
20import org.openstreetmap.josm.Main;
21import org.openstreetmap.josm.command.AddCommand;
22import org.openstreetmap.josm.command.Command;
23import org.openstreetmap.josm.command.SequenceCommand;
24import org.openstreetmap.josm.data.coor.EastNorth;
25import org.openstreetmap.josm.data.osm.Node;
26import org.openstreetmap.josm.data.osm.Way;
27import org.openstreetmap.josm.gui.MapView;
28import org.openstreetmap.josm.gui.PleaseWaitRunnable;
29import org.openstreetmap.josm.io.ProgressInputStream;
30
31public class DownloadSVGBuilding extends PleaseWaitRunnable {
32
33 private WMSLayer wmsLayer;
34 private CadastreGrabber grabber = CadastrePlugin.cadastreGrabber;
35 private CadastreInterface wmsInterface;
36 private String svg = null;
37 private EastNorthBound viewBox = null;
38
39 public DownloadSVGBuilding(WMSLayer wmsLayer) {
40 super(tr("Downloading {0}", wmsLayer.name));
41
42 this.wmsLayer = wmsLayer;
43 this.wmsInterface = grabber.getWmsInterface();
44 }
45
46 @Override
47 public void realRun() throws IOException {
48 Main.pleaseWaitDlg.currentAction.setText(tr("Contacting WMS Server..."));
49 try {
50 if (wmsInterface.retrieveInterface(wmsLayer)) {
51 MapView mv = Main.map.mapView;
52 EastNorthBound enb = new EastNorthBound(mv.getEastNorth(0, mv.getHeight()),
53 mv.getEastNorth(mv.getWidth(), 0));
54 svg = grabBoundary(enb);
55 if (svg == null)
56 return;
57 getViewBox(svg);
58 if (viewBox == null)
59 return;
60 createWay(svg);
61 }
62 } catch (DuplicateLayerException e) {
63 System.err.println("removed a duplicated layer");
64 }
65 }
66
67 @Override
68 protected void cancel() {
69 grabber.getWmsInterface().cancel();
70 }
71
72 @Override
73 protected void finish() {
74 }
75
76 private boolean getViewBox(String svg) {
77 double[] box = new SVGParser().getViewBox(svg);
78 if (box != null) {
79 viewBox = new EastNorthBound(new EastNorth(box[0], box[1]),
80 new EastNorth(box[0]+box[2], box[1]+box[3]));
81 return true;
82 }
83 System.out.println("Unable to parse SVG data (viewBox)");
84 return false;
85 }
86
87 /**
88 * The svg contains more than one commune boundary defined by path elements. So detect
89 * which path element is the best fitting to the viewBox and convert it to OSM objects
90 */
91 private void createWay(String svg) {
92 String[] SVGpaths = new SVGParser().getPaths(svg);
93 ArrayList<ArrayList<EastNorth>> eastNorths = new ArrayList<ArrayList<EastNorth>>();
94 Collection<Node> existingNodes = Main.ds.nodes;
95
96 for (int i=0; i< SVGpaths.length; i++) {
97 ArrayList<EastNorth> eastNorth = new ArrayList<EastNorth>();
98 createNodes(SVGpaths[i], eastNorth);
99 if (eastNorth.size() > 2)
100 eastNorths.add(eastNorth);
101 }
102 List<Way> wayList = new ArrayList<Way>();
103 List<Node> nodeList = new ArrayList<Node>();
104 for (ArrayList<EastNorth> path : eastNorths) {
105 List<Node> tmpNodeList = new ArrayList<Node>();
106 Way wayToAdd = new Way();
107 for (EastNorth eastNorth : path) {
108 Node nodeToAdd = new Node(Main.proj.eastNorth2latlon(eastNorth));
109 // check if new node is not already created by another new path
110 Node nearestNewNode = checkNearestNode(nodeToAdd, tmpNodeList);
111 if (nearestNewNode == nodeToAdd) {
112 // check if new node is not already in existing OSM objects
113 nearestNewNode = checkNearestNode(nodeToAdd, existingNodes);
114 if (nearestNewNode == nodeToAdd)
115 tmpNodeList.add(nodeToAdd);
116 }
117 wayToAdd.nodes.add(nearestNewNode); // either a new node or an existing one
118 }
119 // at least two nodes have to be new, otherwise the polygon is not new (duplicate)
120 if (tmpNodeList.size() > 1) {
121 for (Node n : tmpNodeList)
122 nodeList.add(n);
123 wayToAdd.nodes.add(wayToAdd.nodes.get(0)); // close the way
124 wayList.add(wayToAdd);
125 }
126 }
127 Collection<Command> cmds = new LinkedList<Command>();
128 for (Node node : nodeList)
129 cmds.add(new AddCommand(node));
130 for (Way way : wayList)
131 cmds.add(new AddCommand(way));
132 Main.main.undoRedo.add(new SequenceCommand(tr("Create buildings"), cmds));
133 Main.map.repaint();
134 }
135
136 private void createNodes(String SVGpath, ArrayList<EastNorth> eastNorth) {
137 // looks like "M981283.38 368690.15l143.81 72.46 155.86 ..."
138 String[] coor = SVGpath.split("[MlZ ]"); //coor[1] is x, coor[2] is y
139 double dx = Double.parseDouble(coor[1]);
140 double dy = Double.parseDouble(coor[2]);
141 for (int i=3; i<coor.length; i+=2){
142 if (coor[i].equals("")) {
143 eastNorth.clear(); // some paths are just artifacts
144 return;
145 }
146 double east = dx+=Double.parseDouble(coor[i]);
147 double north = dy+=Double.parseDouble(coor[i+1]);
148 eastNorth.add(new EastNorth(east,north));
149 }
150 // flip the image (svg using a reversed Y coordinate system)
151 double pivot = viewBox.min.getY() + (viewBox.max.getY() - viewBox.min.getY()) / 2;
152 for (EastNorth en : eastNorth) {
153 en.setLocation(en.east(), 2 * pivot - en.north());
154 }
155 return;
156 }
157
158 /**
159 * Check if node can be reused.
160 * @param nodeToAdd the candidate as new node
161 * @return the already existing node (if any), otherwise the new node candidate.
162 */
163 private Node checkNearestNode(Node nodeToAdd, Collection<Node> nodes) {
164 double epsilon = 0.01; // smallest distance considering duplicate node
165 for (Node n : nodes) {
166 if (!n.deleted && !n.incomplete) {
167 double dist = n.eastNorth.distance(nodeToAdd.eastNorth);
168 if (dist < epsilon) {
169 System.out.println("distance="+dist);
170 return n;
171 }
172 }
173 }
174 return nodeToAdd;
175 }
176
177 private String grabBoundary(EastNorthBound bbox) throws IOException {
178
179 try {
180 URL url = null;
181 url = getURLsvg(bbox);
182 System.out.println("grab:"+url);
183 return grabSVG(url);
184 } catch (MalformedURLException e) {
185 throw (IOException) new IOException(tr("CadastreGrabber: Illegal url.")).initCause(e);
186 }
187 }
188
189 private URL getURLsvg(EastNorthBound bbox) throws MalformedURLException {
190 String str = new String(wmsInterface.baseURL+"/scpc/wms?version=1.1&request=GetMap");
191 str += "&layers=";
192 str += "CDIF:LS2";
193 str += "&format=image/svg";
194 str += "&bbox="+bbox.min.east()+",";
195 str += bbox.min.north() + ",";
196 str += bbox.max.east() + ",";
197 str += bbox.max.north();
198 str += "&width=800&height=600"; // maximum allowed by wms server
199 str += "&styles=";
200 str += "LS2_90";
201 System.out.println("URL="+str);
202 return new URL(str.replace(" ", "%20"));
203 }
204
205 private String grabSVG(URL url) throws IOException {
206 wmsInterface.urlConn = (HttpURLConnection)url.openConnection();
207 wmsInterface.urlConn.setRequestMethod("GET");
208 wmsInterface.setCookie();
209 InputStream is = new ProgressInputStream(wmsInterface.urlConn, Main.pleaseWaitDlg);
210 File file = new File(CadastrePlugin.cacheDir + "building.svg");
211 String svg = new String();
212 try {
213 if (file.exists())
214 file.delete();
215 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file, true));
216 InputStreamReader isr =new InputStreamReader(is);
217 BufferedReader br = new BufferedReader(isr);
218 String line="";
219 while ( null!=(line=br.readLine())){
220 line += "\n";
221 bos.write(line.getBytes());
222 svg += line;
223 }
224 bos.close();
225 } catch (IOException e) {
226 e.printStackTrace(System.out);
227 }
228 is.close();
229 return svg;
230 }
231
232 public static void download(WMSLayer wmsLayer) {
233 Main.worker.execute(new DownloadSVGBuilding(wmsLayer));
234 }
235
236}
Note: See TracBrowser for help on using the repository browser.