Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / org.gvsig.arcims / src / org / gvsig / remoteclient / arcims / ArcXMLFeatures.java @ 32538

History | View | Annotate | Download (14.1 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22

    
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2010 Prodevelop S.L. main development
26
 * http://www.prodevelop.es
27
 */
28
package org.gvsig.remoteclient.arcims;
29

    
30
import org.slf4j.Logger;
31
import org.slf4j.LoggerFactory;
32

    
33
import org.gvsig.remoteclient.arcims.utils.GetFeaturesTags;
34
import org.gvsig.remoteclient.arcims.utils.ServiceInfoTags;
35
import org.gvsig.remoteclient.arcims.utils.ServiceInformation;
36

    
37
import java.awt.geom.Rectangle2D;
38

    
39

    
40
/**
41
 * @author jsanz
42
 *
43
 */
44
public class ArcXMLFeatures extends ArcXML {
45
    private static Logger logger = LoggerFactory.getLogger(ArcXMLFeatures.class.getName());
46

    
47
    /**
48
     * Creates a complete request in ArcXML for a FeatureService
49
     * from an ArcImsStatus; including extent, SRS and so on
50
     * @see org.gvsig.remoteclient.arcims.ArcImsStatus#ArcImsStatus()
51
     * @param status
52
     * @return
53
     */
54
    public static String getFeatureLayerRequest(ArcImsVectStatus status) {
55
        return getFeatureLayerRequest(status, 0);
56
    }
57

    
58
    /**
59
     * Creates a complete request in ArcXML for a FeatureService
60
     * from an ArcImsStatus; including extent, SRS and so on
61
     * @see org.gvsig.remoteclient.arcims.ArcImsStatus#ArcImsStatus()
62
     * @param status
63
     * @param featCount
64
     * @return string
65
     */
66
    public static String getFeatureLayerRequest(ArcImsVectStatus status,
67
        int featCount) {
68
        /**
69
             * The layer to retrieve
70
             */
71
        String layerid = (String) status.getLayersIdsSelected().get(0);
72

    
73
        /**
74
        * Gets the Decimal Separator from the status.ServiceInfo
75
        */
76
        ServiceInformation si = status.getServiceInfo();
77
        char ds = si.getSeparators().getDs();
78

    
79
        /**
80
        * The EPSG code that image requested will have,
81
        * the ArcIMS server will reproject data into this
82
        * code, see <a href="http://www.epsg.org">EPSG</a>
83
        */
84
        String srsView = new String();
85

    
86
        /**
87
             * Is the ServiceInfo FeatureCoordsys assumed?
88
             */
89
        boolean srsAssumed = si.isSrsAssumed();
90

    
91
        /**
92
             * We suppose that status.getSrs() always will give a
93
             * string started by this string
94
             */
95
        String ini_srs = ServiceInfoTags.vINI_SRS;
96

    
97
        /**
98
         * Get the minimum distance between points as the mean distance per pixel
99
         */
100
        Rectangle2D geoExtent = status.getEnvelopeRect();
101
        double iX = geoExtent.getWidth() / status.getWidth();
102
        double iY = geoExtent.getHeight() / status.getHeight();
103
        double accuracy = 1.0 * ((iX + iY) / 2.0);
104

    
105
        /**
106
             * Assign the srs from the status
107
             * @see org.gvsig.remoteClient.RemoteClientStatus#getSrs()
108
             */
109
        if (!srsAssumed && status.getSrs().startsWith(ini_srs)) {
110
            srsView = status.getSrs().substring(ini_srs.length()).trim();
111
        } else {
112
            srsView = "";
113
        }
114

    
115
        /**
116
         * Where clause to pass to the server
117
         */
118
        String where = status.getWhere();
119

    
120
        /**
121
        * Finally, we can retrieve the correct ArcXML
122
        */
123
        return getFeaturesRequest(layerid, //layer to retrieve
124
            featCount, //beginrecord
125
            status.getSubfields(), //subfields
126
            where, //where
127
            ArcXML.getFilterCoordsys(srsView), //SRS of the service
128
            ArcXML.getFeatureCoordsys(srsView), //SRS of the view
129
            ArcXML.getEnvelope(geoExtent, ds), //envelope
130
            ArcXML.parseNumber(accuracy * GetFeaturesTags.ACCURACY_RATIO, ds), //accuracy multiplied by an arbitrary ratio
131
            false, //globalenvelope
132
            false, //skipfeatures
133
            true //geometries
134
        );
135
    }
136

    
137
    /**
138
     * Method that builds a proper ArcXML based on basic parameters as fields to retrieve,
139
     * where condition, etc.
140
     * @param layerId
141
     * @param subfields
142
     * @param where
143
     * @param filterCoordsys
144
     * @param featureCoordsys
145
     * @param envelope
146
     * @param globalEnvelope
147
     * @param skipfeatures
148
     * @param geometry
149
     * @return ArcXML request
150
     */
151
    private static String getFeaturesRequest(String layerId, int featCount,
152
        String[] subfields, String where, String filterCoordsys,
153
        String featureCoordsys, String envelope, String accuracy,
154
        boolean globalEnvelope, boolean skipfeatures, boolean geometry) {
155
        String request = new String();
156

    
157
        /**
158
         * Build the SUBFIELDS list
159
         */
160
        String strSubf = new String();
161

    
162
        if (subfields == null) {
163
            subfields = new String[1];
164
            subfields[0] = "#ALL#";
165
        } else {
166
            for (int i = 0; i < subfields.length; i++) {
167
                strSubf += (subfields[i] + " ");
168
            }
169

    
170
            strSubf = strSubf.substring(0, strSubf.length() - 1);
171
        }
172

    
173
        /*
174
         * With newxml we get FIELDS tag with inner FIELD tag for every field of the attribute table,
175
         * this way, we get attribute="#SHAPE#" instead of getting #SHAPE# as a name for an attribute
176
         */
177

    
178
        /*
179
        request = "<?xml version = '1.0' encoding = 'UTF-8'?>\r\n"
180
                        + ArcXML.startRequest("1.1")
181
                        + "\t\t<GET_FEATURES envelope=\"true\" checkesc=\"true\" outputmode=\"newxml\" compact=\"true\"";
182
        */
183
        request = ArcXML.startRequest("1.1") +
184
            "\t\t<GET_FEATURES envelope=\"true\" checkesc=\"true\" outputmode=\"newxml\" compact=\"true\"";
185

    
186
        if (featCount > 0) {
187
            request += (" beginrecord=\"" + featCount + "\"");
188
        }
189

    
190
        if (globalEnvelope) {
191
            request += " globalenvelope=\"true\"";
192
        } else {
193
            request += " globalenvelope=\"false\"";
194
        }
195

    
196
        if (skipfeatures) {
197
            request += " skipfeatures=\"true\"";
198
        } else {
199
            request += " skipfeatures=\"false\"";
200
        }
201

    
202
        if (geometry) {
203
            request += " geometry=\"true\"";
204
        } else {
205
            request += " geometry=\"false\"";
206
        }
207

    
208
        request += (">\r\n" + "\t\t\t<LAYER id=\"" + layerId + "\" />\r\n");
209

    
210
        //Start SPATIALQUERY
211
        request += "\t\t\t\t<SPATIALQUERY  searchorder =\"attributefirst\" ";
212

    
213
        //Put accuracy
214
        if (!accuracy.equals("")) {
215
            request += ("accuracy=\"" + accuracy + "\" ");
216
        }
217

    
218
        //Put subfields
219
        if (!subfields.equals("")) {
220
            request += ("subfields=\"" + strSubf + "\" ");
221
        }
222

    
223
        //Put where
224
        if (!where.equals("")) {
225
            request += ("where=\"" + where + "\" ");
226
        }
227

    
228
        //Close SPATIALQUERY
229
        request += ">\r\n";
230

    
231
        //Put featureCoordsys
232
        if (!featureCoordsys.equals("")) {
233
            request += ("\t\t\t\t" + featureCoordsys + "\r\n");
234
        }
235

    
236
        //Put filterCoordsys
237
        if (!filterCoordsys.equals("")) {
238
            request += ("\t\t\t\t" + filterCoordsys + "\r\n");
239
        }
240

    
241
        //If envelope exists, put SPATIALFILTER
242
        if (!envelope.equals("")) {
243
            request += "\t\t\t\t<SPATIALFILTER relation=\"envelope_intersection\">\r\n";
244
            request += ("\t\t\t\t" + envelope + "\r\n");
245
            request += "\t\t\t\t</SPATIALFILTER>\r\n";
246
        }
247

    
248
        //Close SPATIALQUERY
249
        request += "\t\t\t\t</SPATIALQUERY>\r\n";
250

    
251
        //Close GET_FEATURES
252
        request += "\t\t\t</GET_FEATURES>\r\n";
253

    
254
        //Close request and ArcXML
255
        request += ArcXML.endRequest();
256

    
257
        //Return request
258
        logger.info("\n\tSUBFIELDS=\t" + strSubf + "\n\tWHERE=\t" + where); //System.err.println(request);
259

    
260
        return request;
261
    }
262

    
263
    /**
264
     * @param status
265
     * @return
266
     */
267
    public static String getLayerExtentRequest(ArcImsVectStatus status) {
268
        /*
269
        <?xml version = '1.0' encoding = 'UTF-8'?>
270
        <ARCXML version="1.1">
271
        <REQUEST>
272
        <GET_FEATURES outputmode="newxml" globalenvelope="true" skipfeatures="true">
273
                <LAYER id="1" />
274
                        <SPATIALQUERY subfields="#ALL#" >
275
                                <FEATURECOORDSYS id="4326"/>
276
                        </SPATIALQUERY>
277
                </GET_FEATURES>
278
        </REQUEST>
279
        </ARCXML>
280
                         */
281

    
282
        /**
283
             * The layer to retrieve
284
             */
285
        String layerid = (String) status.getLayersIdsSelected().get(0);
286

    
287
        /**
288
        * Gets the ServiceInfo from the status
289
        */
290
        ServiceInformation si = status.getServiceInfo();
291

    
292
        /**
293
        * The EPSG code that image requested will have,
294
        * the ArcIMS server will reproject data into this
295
        * code, see <a href="http://www.epsg.org">EPSG</a>
296
        */
297
        String srsView = new String();
298
        String srsServ = si.getFeaturecoordsys();
299

    
300
        /**
301
             * Is the ServiceInfo FeatureCoordsys assumed?
302
             */
303
        boolean srsAssumed = si.isSrsAssumed();
304

    
305
        /**
306
             * We suppose that status.getSrs() always will give a
307
             * string started by this string
308
             */
309
        String ini_srs = ServiceInfoTags.vINI_SRS;
310

    
311
        /**
312
             * Assign the srs from the status
313
             * @see org.gvsig.remoteClient.RemoteClientStatus#getSrs()
314
             */
315
        if (!srsAssumed && status.getSrs().startsWith(ini_srs)) {
316
            srsView = status.getSrs().substring(ini_srs.length()).trim();
317
        } else {
318
            srsView = "";
319
            srsServ = "";
320
        }
321

    
322
        /**
323
             * Create a void subfields array
324
             */
325
        String[] strSubf = new String[1];
326
        strSubf[0] = "";
327

    
328
        /**
329
        * Finally, we can retrieve the correct ArcXML
330
        */
331
        return getFeaturesRequest(layerid, //layer to retrieve
332
            0, //beginrecord
333
            strSubf, //subfields
334
            "", //where
335
            ArcXML.getFilterCoordsys(srsServ), //SRS of the service
336
            ArcXML.getFeatureCoordsys(srsView), //SRS of the view
337
            "", //envelope
338
            "", //accuracy
339
            true, //globalenvelope
340
            true, //skipfeatures
341
            false //geometry
342
        );
343
    }
344

    
345
    public static String getAttributesRequest(ArcImsVectStatus status,
346
        int featCount) {
347
        /*
348
        <?xml version = '1.0' encoding = 'UTF-8'?>
349
        <ARCXML version="1.1">
350
        <REQUEST>
351
        <GET_FEATURES outputmode="newxml" geometry="false" envelope="true" globalenvelope="true">
352
        <LAYER id="1" />
353
        <SPATIALQUERY subfields="#ALL#" >
354
        <FILTERCOORDSYS id="4326"/>
355
        <FEATURECOORDSYS id="23030"/>
356
        <SPATIALFILTER relation="area_intersection">
357
                <ENVELOPE minx="-10" miny="38" maxx="2" maxy="41"/>
358
        </SPATIALFILTER>
359
        </SPATIALQUERY>
360
        </GET_FEATURES>
361
        </REQUEST>
362
        </ARCXML>
363
         */
364

    
365
        /**
366
        * The layer to retrieve
367
        */
368
        String layerid = (String) status.getLayersIdsSelected().get(0);
369

    
370
        /**
371
        * Gets the Decimal Separator from the status.ServiceInfo
372
        */
373
        ServiceInformation si = status.getServiceInfo();
374
        char ds = si.getSeparators().getDs();
375

    
376
        /**
377
        * The EPSG code that image requested will have,
378
        * the ArcIMS server will reproject data into this
379
        * code, see <a href="http://www.epsg.org">EPSG</a>
380
        */
381
        String srsView = new String();
382

    
383
        /**
384
             * Is the ServiceInfo FeatureCoordsys assumed?
385
             */
386
        boolean srsAssumed = si.isSrsAssumed();
387

    
388
        /**
389
             * We suppose that status.getSrs() always will give a
390
             * string started by this string
391
             */
392
        String ini_srs = ServiceInfoTags.vINI_SRS;
393

    
394
        /**
395
             * Assign the srs from the status
396
             * @see org.gvsig.remoteClient.RemoteClientStatus#getSrs()
397
             */
398
        if (!srsAssumed && status.getSrs().startsWith(ini_srs)) {
399
            srsView = status.getSrs().substring(ini_srs.length()).trim();
400
        } else {
401
            srsView = "";
402
        }
403

    
404
        /**
405
        * Finally, we can retrieve the correct ArcXML
406
        */
407
        return getFeaturesRequest(layerid, //layer to retrieve
408
            featCount + 1, status.getSubfields(), //subfields
409
            status.getWhere(), //where
410
            ArcXML.getFilterCoordsys(srsView), //SRS of the service
411
            ArcXML.getFeatureCoordsys(srsView), //SRS of the view
412
            ArcXML.getEnvelope(status.getEnvelopeRect(), ds), //envelope
413
            "", //accuracy
414
            true, //GlobalEnvelope
415
            false, //SkipFeatures
416
            false //geometry
417
        );
418
    }
419

    
420
    public static String getAttributesRequest(ArcImsVectStatus statusCloned) {
421
        return getAttributesRequest(statusCloned, 0);
422
    }
423

    
424
    public static String getIdsRequest(ArcImsVectStatus status, int featCount,
425
        String idName) {
426
        String[] idNameA = { idName };
427

    
428
        /**
429
        * Finally, we can retrieve the correct ArcXML
430
        */
431
        return getFeaturesRequest((String) status.getLayersIdsSelected().get(0), //layer to retrieve
432
            featCount, idNameA, //subfields
433
            status.getWhere(), //where
434
            "", //SRS of the service
435
            "", //SRS of the view
436
            "", //envelope
437
            "", //accuracy
438
            true, //GlobalEnvelope
439
            false, //SkipFeatures
440
            false //geometry
441
        );
442
    }
443
}