Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extWMS / src / com / iver / cit / gvsig / wmc / WebMapContext.java @ 7596

History | View | Annotate | Download (35.6 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2005 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41

    
42
/* CVS MESSAGES:
43
*
44
* $Id: WebMapContext.java 7596 2006-09-26 14:41:48Z jaume $
45
* $Log$
46
* Revision 1.7  2006-09-26 14:41:48  jaume
47
* *** empty log message ***
48
*
49
* Revision 1.6  2006/09/25 10:23:26  caballero
50
* Projection
51
*
52
* Revision 1.5  2006/09/15 10:44:24  caballero
53
* extensibilidad de documentos
54
*
55
* Revision 1.4  2006/07/21 10:31:05  jaume
56
* *** empty log message ***
57
*
58
* Revision 1.3  2006/05/24 16:36:28  jaume
59
* *** empty log message ***
60
*
61
* Revision 1.2  2006/05/12 07:47:39  jaume
62
* removed unnecessary imports
63
*
64
* Revision 1.1  2006/05/03 07:51:21  jaume
65
* *** empty log message ***
66
*
67
* Revision 1.10  2006/05/02 15:57:44  jaume
68
* Few better javadoc
69
*
70
* Revision 1.9  2006/04/25 11:40:56  jaume
71
* *** empty log message ***
72
*
73
* Revision 1.8  2006/04/25 10:01:56  jaume
74
* fixed extend bug when importing
75
*
76
* Revision 1.7  2006/04/21 12:46:53  jaume
77
* *** empty log message ***
78
*
79
* Revision 1.6  2006/04/21 11:53:50  jaume
80
* *** empty log message ***
81
*
82
* Revision 1.5  2006/04/21 11:02:25  jaume
83
* few translations
84
*
85
* Revision 1.4  2006/04/21 10:27:32  jaume
86
* exporting now supported
87
*
88
* Revision 1.3  2006/04/20 17:11:54  jaume
89
* Attempting to export
90
*
91
* Revision 1.2  2006/04/19 16:34:29  jaume
92
* *** empty log message ***
93
*
94
* Revision 1.1  2006/04/19 07:57:29  jaume
95
* *** empty log message ***
96
*
97
* Revision 1.1  2006/04/12 17:10:53  jaume
98
* *** empty log message ***
99
*
100
*
101
*/
102
package com.iver.cit.gvsig.wmc;
103

    
104
import java.awt.Dimension;
105
import java.awt.geom.Rectangle2D;
106
import java.io.BufferedReader;
107
import java.io.File;
108
import java.io.FileInputStream;
109
import java.io.FileNotFoundException;
110
import java.io.FileReader;
111
import java.io.IOException;
112
import java.net.URL;
113
import java.util.ArrayList;
114
import java.util.HashMap;
115
import java.util.HashSet;
116
import java.util.Hashtable;
117
import java.util.Vector;
118

    
119
import org.cresques.cts.ICoordTrans;
120
import org.cresques.cts.IProjection;
121
import org.kxml2.io.KXmlParser;
122
import org.xmlpull.v1.XmlPullParserException;
123

    
124
import com.iver.andami.PluginServices;
125
import com.iver.andami.messages.NotificationManager;
126
import com.iver.cit.gvsig.fmap.crs.CRSFactory;
127
import com.iver.cit.gvsig.fmap.drivers.UnsupportedVersionException;
128
import com.iver.cit.gvsig.fmap.exceptions.ImportMapContextException;
129
import com.iver.cit.gvsig.fmap.layers.FLayer;
130
import com.iver.cit.gvsig.fmap.layers.FLayers;
131
import com.iver.cit.gvsig.fmap.layers.FLyrWMS;
132
import com.iver.cit.gvsig.fmap.layers.WMSLayerNode;
133
import com.iver.cit.gvsig.fmap.layers.WMSLayerNode.FMapWMSStyle;
134
import com.iver.cit.gvsig.fmap.rendering.XmlBuilder;
135
import com.iver.cit.gvsig.project.Project;
136
import com.iver.cit.gvsig.project.documents.view.ProjectView;
137

    
138
/**
139
 * Class that loads and produces WebMapContext files and holds its attributes.
140
 *
141
 * You can create a blank WebMapContext instance using the default constructor
142
 * or an already initialized instance by specifying a source file. In the last
143
 * case the file will be readed and the values loaded an holded by the instance.
144
 *
145
 * You can get the equivalent WebMapContext XML document by calling the method
146
 * getXML() supplying the ProjectView that you want to export and depending on
147
 * the value of the fileVersion field (currently you can use "1.1.0" (default),
148
 * "1.0.0" or "0.4.1" to specify the destination document version.
149
 *
150
 * @author jaume dominguez faus - jaume.dominguez@iver.es
151
 */
152
public class WebMapContext {
153
        public final static String FILE_EXTENSION = ".cml";
154

    
155
        static final ArrayList supportedVersions = new ArrayList();
156
        static public final ArrayList exportVersions    = new ArrayList();
157
        static private HashSet supportedLayers = new HashSet();
158
        private File mapContextFile;
159
        private String encoding = "UTF-8";
160
        private String WMC_START_TAG;
161

    
162
        // MapContext stuff
163
        public String fileVersion = null;
164
        public Dimension windowSize = null;
165
        public String srs = null;
166
        public Rectangle2D bBox = null;
167
        public String title = null;
168
        public String id = null;
169
        public String xmlns = null;
170
        public String xmlns_xlink = null;
171
        public String xmlns_xsi = null;;
172
        public String xsi_schemaLocation = null;
173
        public String _abstract = null;
174
        public ArrayList keywordList = null;
175
        public Dimension logoURLSize = null;
176
        public String logoURLFormat = null;
177
        public String logoURL = null;
178
        public String descriptionURLFormat = null;
179
        public String descriptionURL = null;
180
        public boolean contactInfo = false;
181
        public String contactPerson = null;
182
        public String contactOrganization = null;
183
        public String contactPosition = null;
184
        public String address = null;
185
        public String city = null;
186
        public String stateOrProvince = null;
187
        public String postCode = null;
188
        public String country = null;
189
        public String telephone = null;
190
        public String fax = null;
191
        public String email = null;
192

    
193
        private StringBuffer errorMessages;
194

    
195
        /**
196
         * list of FLyrWMS.
197
         */
198
        ArrayList layerList = null;
199

    
200
        /**
201
         * key: server URL (URL)
202
         * value: server title (String)
203
         */
204
        Hashtable serverTitles = null;
205

    
206
        /**
207
         * key: layer FLyrWMS
208
         * value: layer abstract (String)
209
         */
210
        Hashtable layerAbstracts = null;
211

    
212
        /**
213
         * key: layer FLyrWMS
214
         * value: layer formats (String[])
215
         */
216
        Hashtable layerFormats = null;
217

    
218
        /**
219
         * key: layer FLyrWMS
220
         * value: styles (FMapWMSStyle[])
221
         */
222
        Hashtable layerStyles = null;
223

    
224

    
225
        static {
226
                supportedVersions.add("1.1.0");
227
                supportedVersions.add("1.0.0");
228
                supportedVersions.add("0.1.4");
229
        }
230

    
231
        static {
232
                exportVersions.add("1.1.0");
233
                exportVersions.add("1.0.0");
234
                exportVersions.add("0.1.4");
235
        }
236

    
237
        static {
238
                supportedLayers.add(FLyrWMS.class);
239
        }
240

    
241

    
242
        /**
243
         * Initializes the WebMapContext properties from the values in the WebMapContext (.cml)
244
         * file passed in the argument.
245
         * @param file
246
         * @throws UnsupportedVersionException
247
         * @throws ImportMapContextException
248
         */
249
        public void readFile(File file) throws UnsupportedVersionException, ImportMapContextException {
250
                this.mapContextFile = file;
251
                errorMessages = new StringBuffer();
252
                if (getVersion()!=null) {
253
                        if (supportedVersions.contains(getVersion())) {
254
                                WMC_START_TAG = WebMapContextTags.VIEW_CONTEXT;
255
                                if (getVersion().equals("0.1.4")) {
256
                                        WMC_START_TAG = WebMapContextTags.VIEW_CONTEXT_0_1_4;
257
                                        parse1_1_0(file);
258
                                } else if (getVersion().equals("1.1.0")) {
259
                                        parse1_1_0(file);
260
                                } else if (getVersion().equals("1.0.0")) {
261
                                        parse1_1_0(file);
262
                                } else {
263
                                        parseDefaultVersion(file);
264
                                }
265

    
266
                                // Once parsed, check errors
267
                                if (errorMessages.length()>0)
268
                                        throw new ImportMapContextException(errorMessages.toString(), false);
269
                        } else throw new UnsupportedVersionException(PluginServices.getText(this, "file_version")+": "+getVersion());
270
                }
271
        }
272

    
273

    
274
        /**
275
         * If no version was recognized then will parse the default one which is supposed
276
         * to be the best available.
277
         * @param file
278
         */
279
        private void parseDefaultVersion(File file) {
280
                parse1_1_0(file);
281
        }
282

    
283
        /**
284
         * Reads the header of the Weg Map Context file and determines which version
285
         * it belongs to.
286
         * @return String.
287
         */
288
        private String getVersion() {
289
                if (fileVersion == null) {
290
                        String v = null;
291
                        try {
292
                                FileReader fr = new FileReader(mapContextFile);
293
                                KXmlParser parser = new KXmlParser();
294
                                parser.setInput(fr);
295
                                parser.nextTag();
296
                            if ( parser.getEventType() != KXmlParser.END_DOCUMENT )        {
297
                                    if ((parser.getName().compareTo(WebMapContextTags.VIEW_CONTEXT) == 0) ||
298
                                             parser.getName().compareTo(WebMapContextTags.VIEW_CONTEXT_0_1_4) == 0) {
299
                                            v = parser.getAttributeValue("", WebMapContextTags.VERSION);
300
                                    }
301
                            }
302
                        } catch (FileNotFoundException fnfEx) {
303
                        } catch (XmlPullParserException xmlEx) {
304
                                xmlEx.printStackTrace();
305
                        } catch (IOException e) {
306
                        }
307
                        fileVersion = v;
308
                }
309
                return fileVersion;
310
        }
311

    
312
        /**
313
         * Reads a Web Map Context version 1.1.0. As far as v1.0.0 is a subset of
314
         * v1.1.0 it can be used to read files belonging to 1.0.0 as well.
315
         * @param file, the web map context file.
316
         */
317
        private void parse1_1_0(File file) {
318
                try {
319
                        FileReader fr;
320
                        try
321
                    {
322
                                fr = new FileReader(file);
323
                            BufferedReader br = new BufferedReader(fr);
324
                            char[] buffer = new char[100];
325
                            br.read(buffer);
326
                            StringBuffer st = new StringBuffer(new String(buffer));
327
                            String searchText = "encoding=\"";
328
                            int index = st.indexOf(searchText);
329
                            if (index>-1) {
330
                                    st.delete(0, index+searchText.length());
331
                                    encoding = st.substring(0, st.indexOf("\""));
332
                            }
333
                    } catch(FileNotFoundException ex)        {
334
                            ex.printStackTrace();
335
                    } catch (IOException e) {
336
                                e.printStackTrace();
337
                        }
338

    
339
                        fr = new FileReader(file);
340
                        KXmlParser parser = new KXmlParser();
341
                        parser.setInput(new FileInputStream(file), encoding);
342
                        int tag = parser.nextTag();
343
                        if ( parser.getEventType() != KXmlParser.END_DOCUMENT )
344
                        {
345
                                parser.require(KXmlParser.START_TAG, null, WMC_START_TAG);
346
                                while(tag != KXmlParser.END_DOCUMENT) {
347
                                        switch(tag) {
348
                                                case KXmlParser.START_TAG:
349
                                                        if (parser.getName().compareTo(WMC_START_TAG) == 0) {
350
                                                                id = parser.getAttributeValue("", WebMapContextTags.ID);
351
                                                                xmlns = parser.getAttributeValue("", WebMapContextTags.XMLNS);
352
                                                                xmlns_xlink = parser.getAttributeValue("", WebMapContextTags.XMLNS_XLINK);
353
                                                                xmlns_xsi = parser.getAttributeValue("", WebMapContextTags.XMLNS_XSI);
354
                                                                xsi_schemaLocation = parser.getAttributeValue("", WebMapContextTags.XSI_SCHEMA_LOCATION) ;
355
                                                        } else if (parser.getName().compareTo(WebMapContextTags.GENERAL) == 0) {
356
                                                                parseGeneral1_1_0(parser);
357
                                                        } else if (parser.getName().compareTo(WebMapContextTags.LAYER_LIST) == 0) {
358
                                                                int layerListTag = parser.nextTag();
359
                                                                boolean bLayerListEnd = false;
360
                                                                layerList = new ArrayList();
361
                                                                while (!bLayerListEnd) {
362
                                                                        switch(layerListTag) {
363
                                                                        case KXmlParser.START_TAG:
364
                                                                                if (parser.getName().compareTo(WebMapContextTags.LAYER) == 0) {
365
                                                                                        FLyrWMS layer = parseLayer1_1_0(parser);
366
                                                                                        // will use the mapcontext's bounding box as layer's fullextent
367
                                                                                        IProjection proj =  CRSFactory.getCRS(srs);
368
                                                                                        if (proj == null) {
369
                                                                                                // non supported srs, and cannot continue
370
                                                                                                String msg = PluginServices.getText(this, "unsupported_crs") +
371
                                                                                                                         " (" + srs + ")";
372
                                                                                                throw new ImportMapContextException(msg, true);
373
                                                                                        }
374
                                                                                        String[] availableSRS = layer.getSRS().split(",");
375
                                                                                        ICoordTrans ct = null;
376
                                                                                        String mySRS = null;
377
                                                                                        for (int i = 0; i < availableSRS.length; i++) {
378
                                                                                                mySRS = availableSRS[i];
379
                                                                                                IProjection dstProj = CRSFactory.getCRS(mySRS);
380
                                                                                                if (dstProj != null) {
381
                                                                                                        ct = proj.getCT(dstProj);
382
                                                                                                        if (mySRS.equals(srs)) {
383
                                                                                                                // this is the most suitable SRS,
384
                                                                                                                break;
385
                                                                                                        }
386
                                                                                                }
387
                                                                                        }
388

    
389
                                                                                        if (ct != null) {
390
                                                                                                // I've found a supported projection
391
                                                                                                layer.setFullExtent(ct.convert(bBox));
392
                                                                                                layer.setSRS(mySRS);
393
                                                                                        } else {
394
                                                                                                // can't reproject
395
                                                                                                errorMessages.append("[").
396
                                                                                                                      append(PluginServices.getText(this, "layer")).
397
                                                                                                                      append(" ").
398
                                                                                                                      append(layer.getName()).
399
                                                                                                                      append("] ").
400
                                                                                                                          append(PluginServices.getText(this, "cant_reproject_from_any_of")).
401
                                                                                                                          append(" [").append(layer.getSRS()).append("] ").
402
                                                                                                                          append(PluginServices.getText(this, "to")).
403
                                                                                                                          append(srs).
404
                                                                                                                          append("\n");
405

    
406
                                                                                                /*
407
                                                                                                 * will use view's projection and bounding box
408
                                                                                                 * strictly this is incorrect but, at least it allows
409
                                                                                                 * the user to recover by changin layer properties.
410
                                                                                                 */
411
                                                                                                layer.setFullExtent(bBox);
412
                                                                                                layer.setSRS(srs);
413
                                                                                        }
414

    
415
                                                                                        layer.setWmsTransparency(true);
416
                                                                                        layerList.add(layer);
417
                                                                                } else {
418
                                                                    System.out.println("Unrecognized "+parser.getName());
419
                                                                                }
420
                                                                                break;
421
                                                                        case KXmlParser.END_TAG:
422
                                                                                if (parser.getName().compareTo(WebMapContextTags.LAYER_LIST) == 0)
423
                                                                                        bLayerListEnd = true;
424
                                                                                break;
425
                                                                        case KXmlParser.TEXT:
426
                                                                                //System.out.println("[TEXT]["+kxmlParser.getText()+"]");
427
                                                                                break;
428
                                                                        }
429
                                                                        layerListTag = parser.next();
430
                                                                }
431
                                                        } else if (parser.getName().compareTo(WebMapContextTags.DIMENSION_LIST) == 0) {
432
                                                                // TODO
433
                                                                System.out.println("WebMapContext's Dimension not yet implemented");
434
                                                        } else {
435
                                            System.out.println("Unrecognized "+parser.getName());
436
                                                        }
437
                                                        break;
438
                                                case KXmlParser.END_TAG:
439
                                                        break;
440
                                                case KXmlParser.TEXT:
441
                                                        //System.out.println("[TEXT]["+kxmlParser.getText()+"]");
442
                                                        break;
443
                                        }
444
                                        tag = parser.next();
445
                                }
446
                                parser.require(KXmlParser.END_DOCUMENT, null, null);
447
                        }
448
                } catch (Exception e) {
449
                        NotificationManager.addError(PluginServices.getText(this, "map_context_file_error"),e);
450
                        e.printStackTrace();
451
                }
452

    
453
        }
454

    
455
        /**
456
         * Parses the General tag of a web map context 1.1.0 (and 1.0.0) file
457
         * @param parser
458
         * @throws XmlPullParserException
459
         * @throws IOException
460
         */
461
        private void parseGeneral1_1_0(KXmlParser parser) throws XmlPullParserException, IOException {
462
                boolean end = false;
463
            int tag = parser.next();
464
            while (!end) {
465
                    switch(tag) {
466
                        case KXmlParser.START_TAG:
467
                                if (parser.getName().compareTo(WebMapContextTags.WINDOW) == 0) {
468
                                        if (windowSize == null) windowSize = new Dimension();
469
                                                windowSize.setSize(Integer.parseInt(parser.getAttributeValue("", WebMapContextTags.WIDTH)),
470
                                                                                   Integer.parseInt(parser.getAttributeValue("", WebMapContextTags.HEIGHT)));
471
                                } else if (parser.getName().compareTo(WebMapContextTags.BOUNDING_BOX) == 0) {
472
                                        srs = parser.getAttributeValue("", WebMapContextTags.SRS);
473
                                        double minx = Double.parseDouble(parser.getAttributeValue("", WebMapContextTags.X_MIN));
474
                                        double miny = Double.parseDouble(parser.getAttributeValue("", WebMapContextTags.Y_MIN));
475
                                        double maxx = Double.parseDouble(parser.getAttributeValue("", WebMapContextTags.X_MAX));
476
                                        double maxy = Double.parseDouble(parser.getAttributeValue("", WebMapContextTags.Y_MAX));
477
                                        bBox = new Rectangle2D.Double(minx, miny, maxx-minx, maxy-miny);
478
                            } else if (parser.getName().compareTo(WebMapContextTags.TITLE) == 0) {
479
                                        title = parser.nextText();
480
                                } else if (parser.getName().compareTo(WebMapContextTags.ABSTRACT) == 0) {
481
                                        _abstract = parser.nextText();
482
                                } else if (parser.getName().compareTo(WebMapContextTags.KEYWORD_LIST) == 0) {
483
                                        keywordList = new ArrayList();
484
                                        boolean keywordEnd = false;
485
                                    int keywordTag = parser.next();
486
                                    while (!keywordEnd) {
487
                                            switch(keywordTag) {
488
                                                case KXmlParser.START_TAG:
489
                                                        if (parser.getName().compareTo(WebMapContextTags.KEYWORD) == 0) {
490
                                                                keywordList.add(parser.nextText());
491
                                                        } else {
492
                                                    System.out.println("Unrecognized "+parser.getName());
493
                                                                }
494
                                                                break;
495
                                                 case KXmlParser.END_TAG:
496
                                                        if (parser.getName().compareTo(WebMapContextTags.KEYWORD_LIST) == 0)
497
                                                                keywordEnd = true;
498
                                                        break;
499
                                                case KXmlParser.TEXT:
500
                                                        if (parser.getName()!=null)
501
                                                                System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
502
                                                        break;
503
                                            }
504
                                            keywordTag = parser.next();
505
                                    }
506
                                } else if (parser.getName().compareTo(WebMapContextTags.LOGO_URL) == 0) {
507
                                        logoURLSize = new Dimension(Integer.parseInt(parser.getAttributeValue("", WebMapContextTags.WIDTH)),
508
                                                                                                Integer.parseInt(parser.getAttributeValue("", WebMapContextTags.HEIGHT)));
509
                                        logoURLFormat = parser.getAttributeValue("", WebMapContextTags.FORMAT.toLowerCase());
510
                                        parser.nextTag();
511
                                        if (parser.getName().compareTo(WebMapContextTags.ONLINE_RESOURCE) == 0) {
512
                                                logoURL = parser.getAttributeValue("", WebMapContextTags.XLINK_HREF);
513
                                        } else {
514
                                System.out.println("Unrecognized "+parser.getName());
515
                                            }
516
                                } else if (parser.getName().compareTo(WebMapContextTags.DESCRIPTION_URL) == 0) {
517
                                        descriptionURLFormat = parser.getAttributeValue("", WebMapContextTags.FORMAT.toLowerCase());
518
                                        parser.nextTag();
519
                                        if (parser.getName().compareTo(WebMapContextTags.ONLINE_RESOURCE) == 0) {
520
                                                descriptionURL = parser.getAttributeValue("", WebMapContextTags.XLINK_HREF);
521
                                        } else {
522
                                System.out.println("Unrecognized "+parser.getName());
523
                                            }
524
                                } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_INFORMATION) == 0) {
525
                                        boolean contactInfoEnd = false;
526
                                    int contactInfoTag = parser.next();
527
                                    while (!contactInfoEnd) {
528
                                            switch(contactInfoTag) {
529
                                                case KXmlParser.START_TAG:
530
                                                        if (parser.getName().compareTo(WebMapContextTags.CONTACT_PERSON) == 0) {
531
                                                                contactPerson = parser.nextText();
532
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_ORGANIZATION) == 0) {
533
                                                                contactOrganization = parser.nextText();
534
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_POSITION) == 0) {
535
                                                                contactPosition = parser.nextText();
536
                                                        } else if (parser.getName().compareTo(WebMapContextTags.ADDRESS) == 0) {
537
                                                                address = parser.nextText();
538
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CITY) == 0) {
539
                                                                city = parser.nextText();
540
                                                        } else if (parser.getName().compareTo(WebMapContextTags.STATE_OR_PROVINCE) == 0) {
541
                                                                stateOrProvince = parser.nextText();
542
                                                        } else if (parser.getName().compareTo(WebMapContextTags.POSTCODE) == 0) {
543
                                                                postCode = parser.nextText();
544
                                                        } else if (parser.getName().compareTo(WebMapContextTags.COUNTRY) == 0) {
545
                                                                country = parser.nextText();
546
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_VOICE_TELEPHONE) == 0) {
547
                                                                telephone = parser.nextText();
548
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_FACSIMILE_TELEPHONE) == 0) {
549
                                                                fax = parser.nextText();
550
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_ELECTRONIC_MAIL_ADDRESS) == 0) {
551
                                                                email = parser.nextText();
552
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_PERSON_PRIMARY) == 0) {
553
                                                                // DO NOTHING
554
                                                        } else if (parser.getName().compareTo(WebMapContextTags.CONTACT_ADDRESS) == 0) {
555
                                                                // DO NOTHING
556
                                                        } else {
557
                                                    System.out.println("Unrecognized "+parser.getName());
558
                                                                }
559
                                                        break;
560
                                                 case KXmlParser.END_TAG:
561
                                                        if (parser.getName().compareTo(WebMapContextTags.CONTACT_INFORMATION) == 0)
562
                                                                contactInfoEnd = true;
563
                                                        break;
564
                                                case KXmlParser.TEXT:
565
                                                        if (parser.getName()!=null)
566
                                                                System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
567
                                                        break;
568
                                            }
569
                                            contactInfoTag = parser.next();
570
                                    }
571
                            } else {
572
                            System.out.println("Unrecognized "+parser.getName());
573
                                        }
574
                                        break;
575
                         case KXmlParser.END_TAG:
576
                                if (parser.getName().compareTo(WebMapContextTags.GENERAL) == 0)
577
                                        end = true;
578
                                break;
579
                        case KXmlParser.TEXT:
580
                                if (parser.getName()!=null)
581
                                        System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
582
                                break;
583
                    }
584
                    tag = parser.next();
585
            }
586
        }
587

    
588
        private FLyrWMS parseLayer1_1_0(KXmlParser parser) throws XmlPullParserException, IOException {
589
                boolean end = false;
590
                FLyrWMS layer = new FLyrWMS();
591

    
592
                String queryable = parser.getAttributeValue("", WebMapContextTags.QUERYABLE);
593
                layer.setQueryable(queryable!=null && queryable.equals("1"));
594

    
595
                String hidden = parser.getAttributeValue("", WebMapContextTags.HIDDEN);
596
                layer.setVisible(hidden==null || !hidden.equals("1") || !hidden.toLowerCase().equals("true"));
597
            int tag = parser.next();
598
            while (!end) {
599
                    switch(tag) {
600
                        case KXmlParser.START_TAG:
601
                                if (parser.getName().compareTo(WebMapContextTags.SERVER) == 0) {
602
                                        String serverTitle = parser.getAttributeValue("", WebMapContextTags.TITLE.toLowerCase());
603
                                        parser.nextTag();
604
                                        if (parser.getName().compareTo(WebMapContextTags.ONLINE_RESOURCE) == 0) {
605
                                                layer.setHost(new URL(parser.getAttributeValue("", WebMapContextTags.XLINK_HREF)));
606
                                                if (serverTitles == null)
607
                                                    serverTitles = new Hashtable();
608
                                            serverTitles.put(parser.getAttributeValue("", WebMapContextTags.XLINK_HREF), serverTitle);
609
                                        }
610
                                } else if (parser.getName().compareTo(WebMapContextTags.TITLE) == 0) {
611
                                        layer.setName(parser.nextText());
612
                                } else if (parser.getName().compareTo(WebMapContextTags.NAME) == 0) {
613
                                        layer.setLayerQuery(parser.nextText());
614
                                /* //TODO This case would handle nested layer definitions.
615
                                 *
616
                                 } else if (parser.getName().compareTo(WebMapContextTags.LAYER) == 0) {
617
                                        FLyrWMS sonLayer = parseLayer1_1_0(parser);
618
                                        String q = layer.getLayerQuery();
619
                                        if (q == null) q = "";
620
                                        else q += ",";
621
                                        layer.setLayerQuery( q + sonLayer.getLayerQuery());
622
                                 *
623
                                 */
624
                                } else if (parser.getName().compareTo(WebMapContextTags.ABSTRACT) == 0) {
625
                                        if (layerAbstracts == null)
626
                                                layerAbstracts = new Hashtable();
627
                                        layerAbstracts.put(layer, parser.nextText());
628
                                } else if (parser.getName().compareTo(WebMapContextTags.SRS) == 0) {
629
                                        layer.setSRS(parser.nextText());
630
                                } else if (parser.getName().compareTo(WebMapContextTags.FORMAT_LIST) == 0) {
631
                                        int formatsTag = parser.nextTag();
632
                                        boolean bFormatsEnd = false;
633
                                        ArrayList formats = new ArrayList();
634
                                        while (!bFormatsEnd) {
635
                                                switch (formatsTag) {
636
                                                case KXmlParser.START_TAG:
637
                                                        if (parser.getName().compareTo(WebMapContextTags.FORMAT) == 0) {
638
                                                                String current = parser.getAttributeValue("", WebMapContextTags.CURRENT);
639
                                                                String format = parser.nextText();
640
                                                                if (current!=null && current.equals("1"))
641
                                                                        layer.setFormat(format);
642
                                                                formats.add(format);
643
                                                        } else {
644
                                                                System.out.println("Unrecognized "+parser.getName());
645
                                                        }
646
                                                        break;
647
                                                case KXmlParser.END_TAG:
648
                                                        if (parser.getName().compareTo(WebMapContextTags.FORMAT_LIST) == 0)
649
                                                                bFormatsEnd = true;
650
                                                        break;
651
                                                case KXmlParser.TEXT:
652
                                                        if (parser.getName()!=null)
653
                                                                System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
654
                                                        break;
655
                                                }
656
                                                formatsTag = parser.next();
657
                                        }
658
                                        if (layerFormats == null)
659
                                                layerFormats = new Hashtable();
660
                                        layerFormats.put(layer, formats.toArray(new String[0]));
661

    
662
                                } else if (parser.getName().compareTo(WebMapContextTags.STYLE_LIST) == 0) {
663
                                        int stylesTag = parser.nextTag();
664
                                        boolean bStylesEnd = false;
665
                                        ArrayList styles = new ArrayList();
666
                                        while (!bStylesEnd) {
667
                                                switch (stylesTag) {
668
                                                case KXmlParser.START_TAG:
669
                                                        if (parser.getName().compareTo(WebMapContextTags.STYLE) == 0) {
670
                                                                String current = parser.getAttributeValue("", WebMapContextTags.CURRENT);
671
                                                                FMapWMSStyle style = parseStyle1_1_0(parser);
672
                                                                if (current!=null && current.equals("1")) {
673
                                                                        Vector v = new Vector();
674
                                                                        v.add(style.name);
675
                                                                        layer.setStyles(v);
676
                                                                }
677
                                                                styles.add(style);
678
                                                        } else {
679
                                                                System.out.println("Unrecognized "+parser.getName());
680
                                                        }
681
                                                        break;
682
                                                case KXmlParser.END_TAG:
683
                                                        if (parser.getName().compareTo(WebMapContextTags.STYLE_LIST) == 0)
684
                                                                bStylesEnd = true;
685
                                                        break;
686
                                                case KXmlParser.TEXT:
687
                                                        if (parser.getName()!=null)
688
                                                                System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
689
                                                        break;
690
                                                }
691
                                                stylesTag = parser.next();
692
                                        }
693
                                        if (layerStyles == null)
694
                                                layerStyles = new Hashtable();
695

    
696
                                        layerStyles.put(layer, styles.toArray(new FMapWMSStyle[0]));
697
                                } else {
698
                                        System.out.println("Unrecognized "+parser.getName());
699
                                }
700
                                break;
701
                        case KXmlParser.END_TAG:
702
                                if (parser.getName().compareTo(WebMapContextTags.LAYER) == 0)
703
                                        end = true;
704
                                break;
705
                        case KXmlParser.TEXT:
706
                                if (parser.getName()!=null)
707
                                        System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
708
                                break;
709
                    }
710
                    tag = parser.next();
711
            }
712
            return layer;
713
        }
714

    
715
        private FMapWMSStyle parseStyle1_1_0(KXmlParser parser) throws XmlPullParserException, IOException {
716
                boolean end = false;
717
                String styleName = null;
718
                String styleAbstract = null;
719
                String styleTitle = null;
720
            int tag = parser.next();
721
            while (!end) {
722
                    switch(tag) {
723
                        case KXmlParser.START_TAG:
724
                                if (parser.getName().compareTo(WebMapContextTags.NAME) == 0) {
725
                                        styleName = parser.nextText();
726
                                } else if (parser.getName().compareTo(WebMapContextTags.ABSTRACT) == 0) {
727
                                        styleAbstract = parser.nextText();
728
                                } else if (parser.getName().compareTo(WebMapContextTags.TITLE) == 0) {
729
                                        styleTitle = parser.nextText();
730
                                } else {
731
                            System.out.println("Unrecognized "+parser.getName());
732
                                        }
733
                                break;
734
                         case KXmlParser.END_TAG:
735
                                if (parser.getName().compareTo(WebMapContextTags.STYLE) == 0)
736
                                        end = true;
737
                                break;
738
                        case KXmlParser.TEXT:
739
                                if (parser.getName()!=null)
740
                                        System.out.println("[TAG]["+parser.getName()+"]\n[TEXT]["+parser.getText().trim()+"]");
741
                                break;
742
                    }
743
                    tag = parser.next();
744
            }
745
            WMSLayerNode n = new WMSLayerNode();
746
            FMapWMSStyle sty = n.new FMapWMSStyle(styleName, styleTitle, styleAbstract, null);
747
            return sty;
748
        }
749

    
750
        /**
751
         * Creates the Web Map Context (WMC) XML according on the version 1.1.0. Since Web
752
         * WMC 1.0.0 is a subset of WMC 1.1.0 and this method does not produce tags for
753
         * unset values, it can be used to produce WMC 1.0.0, or even to produce
754
         * the deprecated (but still alive) WMC 0.1.4.
755
         * @param v
756
         * @return
757
         */
758
        private String createMapContext1_1_0(ProjectView v) {
759
                ArrayList layersToExport = getExportableLayers(v);
760

    
761
                XmlBuilder xml = new XmlBuilder();
762
                HashMap xmlAttrs = new HashMap();
763
                xml.setEncoding("ISO-8859-1"); // TODO make it customizable???
764
                xml.writeHeader();
765

    
766
                // <ViewContext>
767
                String viewContextTag;
768
                if (fileVersion.equals("0.1.4"))
769
                        viewContextTag = WebMapContextTags.VIEW_CONTEXT_0_1_4;
770
                else
771
                        viewContextTag = WebMapContextTags.VIEW_CONTEXT;
772

    
773
                xml.writeRaw("<!-- "+PluginServices.getText(this, "created_with")+" gvSIG "+Project.VERSION+" -->");
774

    
775
                xmlAttrs.put(WebMapContextTags.VERSION, fileVersion);
776
                xmlAttrs.put(WebMapContextTags.ID, id);
777
                xmlAttrs.put(WebMapContextTags.XMLNS, WebMapContextTags.XMLNS_VALUE);
778
                xmlAttrs.put(WebMapContextTags.XMLNS_XLINK, WebMapContextTags.XMLNS_XLINK_VALUE);
779
                xmlAttrs.put(WebMapContextTags.XMLNS_XSI, WebMapContextTags.XMLNS_XSI_VALUE);
780
                xmlAttrs.put(WebMapContextTags.XSI_SCHEMA_LOCATION, WebMapContextTags.XSI_SCHEMA_LOCATION_VALUE);
781
                xml.openTag(viewContextTag,  xmlAttrs);
782
                xmlAttrs.clear();
783

    
784
                        // <General>
785
                        xml.openTag(WebMapContextTags.GENERAL);
786

    
787
                                // <Window>
788
                                if (windowSize!=null) {
789
                                        xmlAttrs.put(WebMapContextTags.WIDTH, ((int) windowSize.getWidth())+"");
790
                                        xmlAttrs.put(WebMapContextTags.HEIGHT, ((int) windowSize.getHeight())+"");
791
                                        xml.writeTag(WebMapContextTags.WINDOW, xmlAttrs);
792
                                        xmlAttrs.clear();
793
                                }
794
                                // </Window>
795

    
796
                                // <BoundingBox>
797
                                xmlAttrs.put(WebMapContextTags.SRS, v.getProjection().getAbrev());
798
                                xmlAttrs.put(WebMapContextTags.X_MIN, bBox.getMinX()+"");
799
                                xmlAttrs.put(WebMapContextTags.Y_MIN, bBox.getMinY()+"");
800
                                xmlAttrs.put(WebMapContextTags.X_MAX, bBox.getMaxX()+"");
801
                                xmlAttrs.put(WebMapContextTags.Y_MAX, bBox.getMaxY()+"");
802
                                xml.writeTag(WebMapContextTags.BOUNDING_BOX, xmlAttrs);
803
                                xmlAttrs.clear();
804
                                // </BoundingBox>
805

    
806
                                // <Title>
807
                                xml.writeTag(WebMapContextTags.TITLE, title.trim());
808
                                // </Title>
809

    
810
                                // <Abstract>
811
                                if (_abstract != null)
812
                                        xml.writeTag(WebMapContextTags.ABSTRACT, _abstract.trim());
813
                                // </Abstract>
814

    
815
                                // <LogoURL>
816
                                if (logoURL != null)
817
                                        xml.writeTag(WebMapContextTags.LOGO_URL, logoURL.trim());
818
                                // </LogoURL>
819

    
820
                                // <DescriptionURL>
821
                                if (descriptionURL != null)
822
                                        xml.writeTag(WebMapContextTags.DESCRIPTION_URL, descriptionURL.trim());
823
                                // </DescriptionURL>
824

    
825
                                if (contactInfo) {
826

    
827
                                        // <ContactInformation>
828
                                        xml.openTag(WebMapContextTags.CONTACT_INFORMATION);
829
                                        if (contactPerson != null || contactOrganization != null) {
830

    
831
                                                // <ContactPersonPrimary>
832
                                                xml.openTag(WebMapContextTags.CONTACT_PERSON_PRIMARY);
833

    
834
                                                        // <ContactPerson>
835
                                                        if (contactPerson != null)
836
                                                                xml.writeTag(WebMapContextTags.CONTACT_PERSON, contactPerson.trim());
837
                                                        // </ContactPerson>
838

    
839
                                                        // <ContactOrganization>
840
                                                        if (contactOrganization != null)
841
                                                                xml.writeTag(WebMapContextTags.CONTACT_ORGANIZATION, contactOrganization.trim());
842
                                                        // </ContactOrganization>
843

    
844
                                                xml.closeTag();
845
                                                // </ContactPersonPrimary>
846
                                        }
847
                                        xml.closeTag();
848
                                        // </ContactInformation>
849

    
850
                                        // <ContactPosition>
851
                                        if (contactPosition != null)
852
                                                xml.writeTag(WebMapContextTags.CONTACT_POSITION, contactPosition.trim());
853
                                        // </ContactPosition>
854

    
855
                                        // <ContactAddress>
856
                                        if (address != null || city != null || stateOrProvince != null || postCode != null || country != null) {
857
                                                xml.openTag(WebMapContextTags.CONTACT_ADDRESS);
858

    
859
                                                        // <AddressType>
860
                                                        xml.writeTag(WebMapContextTags.ADDRESS_TYPE, "Postal");
861
                                                        // </AddressType>
862

    
863
                                                        // <Address>
864
                                                        if (address != null)
865
                                                                xml.writeTag(WebMapContextTags.ADDRESS, address.trim());
866
                                                        // </Address>
867

    
868
                                                        // <City>
869
                                                        if (city != null)
870
                                                                xml.writeTag(WebMapContextTags.CITY, city.trim());
871
                                                        // </City>
872

    
873
                                                        // <StateOrProvince>
874
                                                        if (stateOrProvince != null)
875
                                                                xml.writeTag(WebMapContextTags.STATE_OR_PROVINCE, stateOrProvince.trim());
876
                                                        // </StateOrProvince>
877

    
878
                                                        // <PostCode>
879
                                                        if (postCode != null)
880
                                                                xml.writeTag(WebMapContextTags.POSTCODE, postCode.trim());
881
                                                        // </PostCode>
882

    
883
                                                        // <Country>
884
                                                        if (country != null)
885
                                                                xml.writeTag(WebMapContextTags.COUNTRY, country.trim());
886
                                                        // </Country>
887
                                                xml.closeTag();
888
                                        }
889
                                        // </ContactAddress>
890

    
891
                                        // <ContactVoiceTelephone>
892
                                        if (telephone != null)
893
                                                xml.writeTag(WebMapContextTags.CONTACT_VOICE_TELEPHONE, telephone.trim());
894
                                        // </ContactVoiceTelephone>
895

    
896
                                        // <ContactFacsimileTelephone>
897
                                        if (fax != null)
898
                                                xml.writeTag(WebMapContextTags.CONTACT_FACSIMILE_TELEPHONE, fax.trim());
899
                                        // </ContactFacsimileTelephone>
900

    
901
                                        // <ContactElectronicMailAddress>
902
                                        if (email != null)
903
                                                xml.writeTag(WebMapContextTags.CONTACT_ELECTRONIC_MAIL_ADDRESS, email.trim());
904
                                        // </ContactElectronicMailAddress>
905
                                }
906
                                // <KeywordList>
907
                                xml.openTag(WebMapContextTags.KEYWORD_LIST);
908
                                if (keywordList != null) {
909
                                        for (int i = 0; i < keywordList.size(); i++) {
910
                                                xml.writeTag(WebMapContextTags.KEYWORD, ((String) keywordList.get(i)).trim());
911
                                        }
912
                                } else {
913
                                        xml.writeTag(WebMapContextTags.KEYWORD, "");
914
                                }
915
                                xml.closeTag();
916

    
917
                                // </KeywordList>
918
                        xml.closeTag();
919
                        // </General>
920

    
921
                        // <LayerList>
922
                        xml.openTag(WebMapContextTags.LAYER_LIST);
923
                        for (int i = 0; i < layersToExport.size(); i++) {
924
                                xml.writeRaw(((FLyrWMS) layersToExport.get(i)).toMapContext(fileVersion));
925
                        }
926
                        xml.closeTag();
927
                        // </LayerList>
928
                xml.closeTag();
929
                // </ViewContext>
930

    
931
                return xml.getXML();
932
        }
933

    
934
        /**
935
         * Exports the ProjectView passed as parameter to Web Map Context XML compliant
936
         * with the defined specifications for the version set in the fileVersion field.
937
         * @param ProjectView to be exported
938
         * @return String containing the XML
939
         */
940
        public String toXML(ProjectView v) {
941
                if (fileVersion.equals("1.1.0") ||
942
                                fileVersion.equals("1.0.0") ||
943
                                fileVersion.equals("0.1.4")) {
944
                        return createMapContext1_1_0(v);
945
                }
946
                return null;
947
        }
948

    
949

    
950
        public static ArrayList getExportableLayers(ProjectView v) {
951
                ArrayList list = new ArrayList();
952
                FLayers lyrs = v.getMapContext().getLayers();
953
                list.addAll(_getExportableLayers(lyrs));
954
                return list;
955
        }
956

    
957
        private static ArrayList _getExportableLayers(FLayer lyr) {
958
                ArrayList list = new ArrayList();
959
                if (checkType(lyr)) {
960
                        list.add(lyr);
961
                } else {
962
                        if (lyr instanceof FLayers) {
963
                                FLayers lyrs = (FLayers) lyr;
964
                                for (int i = 0; i < lyrs.getLayersCount(); i++) {
965
                                        list.addAll(_getExportableLayers(lyrs.getLayer(i)));
966
                                }
967
                        }
968
                }
969
                return list;
970
        }
971

    
972
        /**
973
         * Checks if the layer is supported by the WebMapContext
974
         * @param lyr
975
         * @return
976
         */
977
        private static boolean checkType(FLayer lyr) {
978
                return supportedLayers.contains(lyr.getClass());
979
        }
980

    
981
        /**
982
         * Searches in the layer tree of the TOC for an ocurrence of any
983
         * exportable layer and returns true if so, or false otherwise.
984
         * @param layer
985
         * @return
986
         */
987
        public static boolean containsExportableLayers(FLayer layer) {
988
                if (checkType(layer))
989
                        return true;
990

    
991
                if (layer instanceof FLayers) {
992
                        FLayers layers = (FLayers) layer;
993
                        for (int i = 0; i < layers.getLayersCount(); i++) {
994
                                FLayer lyr = layers.getLayer(i);
995
                                if (containsExportableLayers(lyr))
996
                                        return true;
997

    
998
                        }
999
                }
1000
                return false;
1001
        }
1002
}