Statistics
| Revision:

root / branches / v10 / extensions / extPublishMapserver / src / org / gvsig / publish / mapserver / model / wms / MapserverWMSLayer.java @ 22362

History | View | Annotate | Download (17.1 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004-2006 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 Iba?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
package org.gvsig.publish.mapserver.model.wms;
42

    
43
import java.awt.Color;
44
import java.awt.geom.Rectangle2D;
45
import java.io.File;
46
import java.io.IOException;
47
import java.io.UnsupportedEncodingException;
48

    
49
import org.gvsig.publish.PublishLogger;
50
import org.gvsig.publish.infoproject.IDataSourceInfo;
51
import org.gvsig.publish.infoproject.ILayerInfo;
52
import org.gvsig.publish.infoproject.ISymbolInfo;
53
import org.gvsig.publish.infoproject.datasources.IDataBaseInfo;
54
import org.gvsig.publish.infoproject.legends.IIntervalLegendInfo;
55
import org.gvsig.publish.infoproject.legends.ISingleSymbolLegendInfo;
56
import org.gvsig.publish.infoproject.legends.IUniqueValuesLegendInfo;
57
import org.gvsig.publish.infoproject.symbols.IFillSymbolInfo;
58
import org.gvsig.publish.infoproject.symbols.ILineSymbolInfo;
59
import org.gvsig.publish.infoproject.symbols.IMarkerSymbolInfo;
60
import org.gvsig.publish.infoproject.symbols.ITextSymbolInfo;
61
import org.gvsig.publish.mapserver.conf.MapFile;
62
import org.gvsig.publish.mapserver.conf.MapFile.CRS;
63
import org.gvsig.publish.mapserver.conf.MapFile.ConfigFile;
64
import org.gvsig.publish.mapserver.conf.MapFile.Label;
65
import org.gvsig.publish.mapserver.conf.MapFile.Layer;
66
import org.gvsig.publish.mapserver.conf.MapFile.MapClass;
67
import org.gvsig.publish.mapserver.conf.MapFile.RGB;
68
import org.gvsig.publish.mapserver.conf.MapFile.StyleMap;
69
import org.gvsig.publish.mapserver.model.Mapserver;
70
import org.gvsig.publish.mapserver.model.MapserverLayer;
71
import org.gvsig.publish.mapserver.util.MapserverUtilities;
72
import org.gvsig.publish.ogcmetadata.IOGCLayerMetadata;
73
import org.gvsig.publish.ogcmetadata.OGCLayerMetadata;
74
import org.gvsig.publish.serversmodel.PublishException;
75
import org.gvsig.publish.serversmodel.RemoteResource;
76

    
77
import com.iver.utiles.FileUtils;
78
import com.iver.utiles.XMLEntity;
79
/**
80
 * This class represents a kind of remote resource, a Mapserver-WMS layer.   
81
 * 
82
 * @author jvhigon
83
 *
84
 */
85
public class MapserverWMSLayer extends RemoteResource implements IOGCLayerMetadata{
86
        public static final String REGISTER_TAG="mapserver_wms_layer";
87
        //Associations        
88
        private OGCLayerMetadata ogcmetadata = null;
89
        private MapserverLayer specificParams = null;
90
        private MapFile.Layer config = null;
91
        /**
92
         * Constructor
93
         * @param service
94
         */
95
        public MapserverWMSLayer(MapserverWMS service){
96
                super(service);                
97
                ogcmetadata = new OGCLayerMetadata();
98
                specificParams = new MapserverLayer();                        
99
        }
100

    
101
        public MapserverLayer getLayerMapserver() {
102
                return specificParams;
103
        }
104

    
105
        public void setLayerMapserver(MapserverLayer layerMapserver) {
106
                this.specificParams = layerMapserver;
107
        }
108

    
109
        private ConfigFile getMapfile(){
110
                MapserverWMS wms = (MapserverWMS)getService();
111
                Mapserver server = (Mapserver) wms.getServer();
112
                return server.getConfigFile();
113
        }
114

    
115

    
116
        /**
117
         * Initializes the remote resource name and title with the name and title of the layer
118
         */
119
        public void setLayerInfo(ILayerInfo layerInfo) {
120
                super.setLayerInfo(layerInfo);
121
                setName(getLayerInfo().getName());
122
                setTitle(getLayerInfo().getTitle());
123
        }
124
        
125
        private Mapserver getMapServer(){
126
                //Cast to Mapserver
127
                Mapserver mapserver = (Mapserver)getService().getServer();
128
                return mapserver;
129
        }
130
        /**
131
         * Generates a new layer configuration in the mapfile when is invoked
132
         * @see org.gvsig.publish.serversmodel.RemoteResource#publish()
133
         */
134
        public void publish() throws PublishException{
135
                //only for no group layers
136
                //TODO: wms_group_abstract ...
137
                if (getLayerInfo().getDataSource() != null){
138
                        config = new MapFile.Layer();
139
                        getMapfile().add(config);
140
                        generateLayerSection();
141
                }
142

    
143
                //publish all its childs                
144
                super.publish();
145
        }
146
        
147
        private void generateLayerSection() throws PublishException{                
148
                
149
                config.name = getName();
150
                config.status = "ON";
151
                config.debug = getMapServer().isDebug();
152
                config.type = MapserverUtilities.getTypeParameter(getLayerInfo().getDataSource());
153
                generateDataParameter();                
154
                config.connectiontype = MapserverUtilities.getConnectionTypeParameter(getLayerInfo().getDataSource());
155
                config.connection = MapserverUtilities.getConnectionParameter(getLayerInfo().getDataSource());                
156
                config.maxscale = new Double(getLayerInfo().getMaxscale()).toString();
157
                config.minscale = new Double(getLayerInfo().getMinscale()).toString();
158
                config.transparency = getLayerInfo().getOpacityPercent();
159
                config.dump = isQueryable();                
160
                
161
                //mosaic 
162
                generateMosaicSection();
163
                //labeling
164
                generateLabelingSection();
165
                //PROJECTION (I must query the layer to know the shape projection)
166
                //lyr.layercrs = new CRS(getLayerInfo().getEPSG(),true);
167
                config.layercrs = new CRS(getLayerInfo().getDataSource().getEPSG(),true);
168
                
169
                //CLASS
170
                generateClassSection();
171
                //METADATA
172
                generateMetadata(config);
173

    
174
        }
175
        /**
176
         * Generates the LAYER->DATA parameter 
177
         */
178
        private void generateDataParameter() {
179
                IDataSourceInfo ds = getLayerInfo().getDataSource();
180
                if (ds.getType() == IDataSourceInfo.POSTGIS_TYPE){
181
                        IDataBaseInfo db = (IDataBaseInfo)ds;
182
                        String table = db.getTableName();
183
                        config.data ="the_geom from "  + table + " using unique " + db.getGID() + " using srid=" + ds.getSRID(); 
184
                }else{
185
                        config.data = getService().getServer().getPublication().getServerSideFilePath(ds);
186
                }                                
187
        }
188

    
189
        private void generateMosaicSection() {
190
                if (getSpecificParams().isMosaic()){
191
                        config.type = "RASTER";
192
                        config.tileIndex = getService().getServer().getPublication().getServerSideFilePath(getLayerInfo().getDataSource());
193
                        config.data = null;
194
                        config.classList.clear();
195
                        config.tileItem="location";
196
                }
197
                
198
        }
199

    
200
        /**
201
         * TODO:
202
         * lyr.labelsizeitem = getLayerInfo().getLabeling().getLabelHeightField();
203
         * lyr.labelangleitem = getLayerInfo().getLabeling().getLabelRotationField();
204
         */
205
        private void generateLabelingSection(){
206
                if (getLayerInfo().getLabeling() != null){
207
                        config.labelitem = getLayerInfo().getLabeling().getLabelField();
208
                        
209
                }                
210
        }
211
        private void generateClassSection() throws PublishException{
212
                //CLASS
213
                Object source = getLayerInfo().getLegend();                
214
                if(source instanceof ISingleSymbolLegendInfo){
215
                        ISingleSymbolLegendInfo legend = (ISingleSymbolLegendInfo)source;
216
                        generateSingleLegend(legend, config);                
217
                }
218
                if(source instanceof IUniqueValuesLegendInfo){
219
                        IUniqueValuesLegendInfo legend = (IUniqueValuesLegendInfo)source;
220
                        generateUniqueLegend(legend, config);                        
221
                }
222
                if(source instanceof IIntervalLegendInfo){
223
                        IIntervalLegendInfo legend = (IIntervalLegendInfo)source;
224
                        generateIntervalLegend(legend, config);                        
225
                }
226
        }
227

    
228
        private void generateSingleLegend(ISingleSymbolLegendInfo legend, Layer lyr) throws PublishException {
229
                ISymbolInfo isymbol =  legend.getSymbolInfo();                
230
                lyr.classList.clear();
231
                MapClass clase = new MapClass();                
232
                //put name
233
                clase.name = "default";
234
                //put the size units
235
                lyr.sizeunits = isymbol.getUnits();
236

    
237
                generateStyle(isymbol, clase);
238
                //put labeling if exists
239
                if ( getLayerInfo().getLabeling().getLabelField() != null){
240
                        generateSymbol(getLayerInfo().getLabeling().getSymbolInfo(), clase);
241
                        
242
                }
243
                //add the class into the layer
244
                lyr.addClass(clase);                
245
        }
246

    
247

    
248
        /**
249
         * Generate an interval legend
250
         * @param legend
251
         * The legend
252
         * @param lyr
253
         * The layer
254
         * @throws PublishException 
255
         */
256
        private void generateIntervalLegend(IIntervalLegendInfo legend, Layer lyr) throws PublishException {
257
                //check if is labeled
258
                boolean islabeled = false;
259
                if ( getLayerInfo().getLabeling().getLabelField() != null){
260
                        islabeled = true;
261
                }
262
                
263
                String[] expressions = legend.getExpressions();
264
                for (int i=0 ; i<expressions.length ; i++){
265
                        ISymbolInfo isymbol = legend.getSymbolByExpression(expressions[i]);
266
                        MapClass clase = new MapClass();
267
                        clase.name = isymbol.getTitle();
268
                        //TODO: change in infoProject
269
                        clase.expression = "(" + expressions[i] + ")";
270
                        generateStyle(isymbol, clase);
271
                        if (islabeled){
272
                                generateSymbol(getLayerInfo().getLabeling().getSymbolInfo(), clase);
273
                        }
274
                        lyr.addClass(clase);
275
                }
276
        }
277

    
278
        private void generateUniqueLegend(IUniqueValuesLegendInfo legend, Layer lyr) throws PublishException {
279
                //check if is labeled
280
                boolean islabeled = false;
281
                if ( getLayerInfo().getLabeling().getLabelField() != null){
282
                        islabeled = true;
283
                }
284
                //put the CLASSITEM
285
                lyr.classitem = legend.getFilterItem();
286
                //create all CLASS
287
                String[] uniqueValues = legend.getUniqueValues();
288
                for (int i =0; i< uniqueValues.length;i++){
289
                        ISymbolInfo isymbol = legend.getSymbol(uniqueValues[i]);
290
                        //create a CLASS
291
                        MapClass clase = new MapClass();
292
                        clase.name = isymbol.getTitle();
293
                        //TODO: change in infoProject                        
294
                        clase.expression = "\"" +  uniqueValues[i] + "\"";
295
                        generateStyle(isymbol, clase);
296
                        if (islabeled){
297
                                generateSymbol(getLayerInfo().getLabeling().getSymbolInfo(), clase);
298
                        }
299
                        //add the class into the layer
300
                        lyr.addClass(clase);
301
                }
302
        }
303

    
304
        private void generateStyle(ISymbolInfo isymbol, MapClass clase) throws PublishException{                
305
                if (getLayerInfo().getDataSource().getDataType() == IDataSourceInfo.POINT_DATA){
306
                        //I can do a cast to Marker Symbol
307
                        IMarkerSymbolInfo pointSymbol = (IMarkerSymbolInfo)isymbol;
308
                        generateSymbol(pointSymbol, clase);
309
                }
310
                if (getLayerInfo().getDataSource().getDataType() == IDataSourceInfo.LINE_DATA){
311
                        //I can do a cast to Line Symbolizer
312
                        ILineSymbolInfo lineSymbol = (ILineSymbolInfo)isymbol;
313
                        generateSymbol(lineSymbol, clase);
314
                }        
315
                if (getLayerInfo().getDataSource().getDataType() == IDataSourceInfo.POLYGON_DATA){
316
                        //I can do a cast to Polygon Symbolizer
317
                        IFillSymbolInfo fillSymbol = (IFillSymbolInfo)isymbol;
318
                        generateSymbol(fillSymbol, clase);
319
                }
320

    
321
        }
322

    
323
        private void generateSymbol(ITextSymbolInfo textSymbol, MapClass clase){
324
                clase.etiqueta = new Label();
325
                //TODO: change by getColor()
326
                Color c = textSymbol.getFontColor();
327
                clase.etiqueta.color = new RGB(c.getRed(), c.getGreen(), c.getBlue());
328
                clase.etiqueta.angle = "[" + getLayerInfo().getLabeling().getLabelRotationField() + "]";
329

    
330
                //clase.etiqueta.size = new Double(textSymbol.getFontSize()).intValue();
331
                //clase.etiqueta.type = "truetype";
332
        }
333

    
334
        private void generateSymbol(IMarkerSymbolInfo pointSymbol, MapClass clase) throws PublishException {
335
                clase.estilo = new StyleMap();                
336
                Color c = pointSymbol.getColor();
337
                clase.estilo.styleColor = new RGB(c.getRed(), c.getGreen(), c.getBlue());
338
                clase.estilo.size = pointSymbol.getSize();
339
                clase.symbol = pointSymbol.getWellKnowMarkerName();
340
                //if it's an image
341
                File icon = pointSymbol.getImageIconFile(); 
342
                if ( icon !=null){
343
                        clase.symbol = icon.getName();
344
                        Mapserver m = (Mapserver)getService().getServer();
345
                        String s = m.getMapfileFile().getParentFile().getAbsolutePath();
346
                        File dst = new File(s+ File.separator+ icon.getName());
347
                        
348
                        try {
349
                                FileUtils.copy(icon, dst);
350
                        } catch (IOException e) {                        
351
                                throw new PublishException("cannot_copy_icons");                        
352
                        }
353
                }
354
                
355
        }
356
        /**
357
         * In Mapserver is impossible to have a dashed outline 
358
         * @param fillSymbol
359
         * @param clase
360
         */
361
        private void generateSymbol(IFillSymbolInfo fillSymbol, MapClass clase) {
362
                clase.estilo = new StyleMap();
363
                //set outline                
364
                ILineSymbolInfo linesymbolizer = fillSymbol.getOutline();
365
                Color c = linesymbolizer.getColor();
366
                clase.estilo.styleColorOutline = new RGB(c.getRed(), c.getGreen(), c.getBlue());
367
                clase.estilo.width = new Double(linesymbolizer.getLineWitdth()).intValue();                
368
                //set fill
369
                c = fillSymbol.getColor();
370
                clase.estilo.styleColor = new RGB(c.getRed(), c.getGreen(), c.getBlue());                                
371
                //if it is a well known polygon
372
                clase.symbol = fillSymbol.getWellKnowFillName();
373
        }
374

    
375
        private void generateSymbol(ILineSymbolInfo lineSymbol, MapClass clase) {
376
                Color c = lineSymbol.getColor();                
377
                clase.estilo = new StyleMap();
378
                clase.estilo.width = new Double(lineSymbol.getLineWitdth()).intValue();
379
                clase.estilo.styleColor = new RGB(c.getRed(), c.getGreen(), c.getBlue());
380
                //if it is a well know line
381
                clase.symbol = lineSymbol.getWellKnowLineName();
382
        }
383

    
384
        /**
385
         * Generates the METADATA object
386
         * @param mapLayer
387
         */
388
        private void generateMetadata(Layer mapLayer){
389
                //add metadata
390
                mapLayer.metadata.wms_name = getName();
391
                mapLayer.metadata.wms_title =getTitle();
392
                mapLayer.metadata.wms_abstract = getAbstract();
393
                Rectangle2D aux = getLayerInfo().getDataSource().getNativeBBox();
394
                String bbox = aux.getMinX() + " " + aux.getMinY() + " " + aux.getMaxX() + " " + aux.getMaxY();
395
                mapLayer.metadata.wms_extent = bbox;
396
                mapLayer.metadata.gml_include_items = "all";         
397
                //adding layer_group
398
        
399
                if (getLayerInfo().getPathString().equals("/")==false){
400
                        String aux2 = getLayerInfo().getPathString();
401
                        mapLayer.metadata.wms_layer_group = aux2.substring(0,aux2.length()-1);
402
                }
403
        }
404
        
405
        /*
406
         * (non-Javadoc)
407
         * @see com.iver.utiles.IPersistance#getClassName()
408
         */
409
        public String getClassName() {        
410
                return "MapserverWMSLayer";
411
        }
412
        /*
413
         * (non-Javadoc)
414
         * @see org.gvsig.publish.serversmodel.RemoteResource#getXMLEntity()
415
         */
416
        public XMLEntity getXMLEntity() {
417
                XMLEntity xml=super.getXMLEntity();
418
                //put version and name
419
                xml.setName(getClassName());
420
                xml.putProperty("version", getVersion());
421
                //put associations
422
                XMLEntity child = new XMLEntity();
423
                child.setName("ogcmetadata");
424
                child.addChild(ogcmetadata.getXMLEntity());
425
                xml.addChild(child);
426
                child = new XMLEntity();
427
                child.setName("mapserverlayer");
428
                child.addChild(specificParams.getXMLEntity());
429
                xml.addChild(child);        
430
                return xml;
431
        }
432
        /*
433
         * (non-Javadoc)
434
         * @see org.gvsig.publish.serversmodel.RemoteResource#setXMLEntity(com.iver.utiles.XMLEntity)
435
         */
436
        public void setXMLEntity(XMLEntity xml) {
437
                //check version
438
                int version = xml.getIntProperty("version");
439
                if (version != getVersion()){
440
                        PublishLogger.getLog().error("ERROR: " + getClassName() + ": the version doesn't match!");                        
441
                        return;
442
                }
443
                super.setXMLEntity(xml);                                                
444
                //set associations
445
                XMLEntity child = xml.firstChild("name","ogcmetadata");
446
                ogcmetadata.setXMLEntity(child.getChild(0));                
447
                child = xml.firstChild("name","mapserverlayer");
448
                specificParams.setXMLEntity(child.getChild(0));
449
        }
450

    
451
        /*
452
         * (non-Javadoc)
453
         * @see org.gvsig.publish.serversmodel.RemoteResource#getId()
454
         */
455
        public String getId() {                
456
                return getLayerInfo().getName();
457
        }
458

    
459
        /*
460
         * (non-Javadoc)
461
         * @see org.gvsig.publish.IPublishPersistence#getVersion()
462
         */
463
        public int getVersion() {                
464
                return 1;
465
        }
466
        /*
467
         * (non-Javadoc)
468
         * @see org.gvsig.publish.ogcmetadata.IOGCWMSLayerMetadata#isQueryable()
469
         */
470
        public boolean isQueryable() {
471
                return ogcmetadata.isQueryable();
472
        }
473
        /*
474
         * (non-Javadoc)
475
         * @see org.gvsig.publish.ogcmetadata.IOGCWMSLayerMetadata#setQueryable(boolean)
476
         */
477
        public void setQueryable(boolean queryable) {
478
                ogcmetadata.setQueryable(queryable);                
479
        }
480
        /*
481
         * (non-Javadoc)
482
         * @see org.gvsig.publish.ogcmetadata.IOGCCommonMetadata#getAbstract()
483
         */
484
        public String getAbstract() {                
485
                return ogcmetadata.getAbstract();
486
        }
487
        /*
488
         * (non-Javadoc)
489
         * @see org.gvsig.publish.ogcmetadata.IOGCCommonMetadata#getName()
490
         */
491
        public String getName() {                
492
                return ogcmetadata.getName();
493
        }
494
        /*
495
         * (non-Javadoc)
496
         * @see org.gvsig.publish.ogcmetadata.IOGCCommonMetadata#setAbstract(java.lang.String)
497
         */
498
        public void setAbstract(String description) {
499
                ogcmetadata.setAbstract(description);                
500
        }
501
        /*
502
         * (non-Javadoc)
503
         * @see org.gvsig.publish.ogcmetadata.IOGCCommonMetadata#setName(java.lang.String)
504
         */
505
        public void setName(String name) {
506
                ogcmetadata.setName(name);                
507
        }
508
        /*
509
         * (non-Javadoc)
510
         * @see org.gvsig.publish.ogcmetadata.IOGCCommonMetadata#setTitle(java.lang.String)
511
         */
512
        public void setTitle(String title) {
513
                ogcmetadata.setTitle(title);                
514
        }
515
        /*
516
         * (non-Javadoc)
517
         * @see org.gvsig.publish.ogcmetadata.IOGCCommonMetadata#getTitle()
518
         */
519
        public String getTitle() {                
520
                return ogcmetadata.getTitle();
521
        }
522

    
523
        /*
524
         * (non-Javadoc)
525
         * @see org.gvsig.publish.serversmodel.RemoteResource#getRegisterTag()
526
         */
527
        public String getRegisterTag() {                
528
                return REGISTER_TAG;
529
        }
530
        /*
531
         * (non-Javadoc)
532
         * @see java.lang.Object#toString()
533
         */
534
        public String toString(){
535
                return getName();
536
        }
537

    
538
        /**
539
         * @return the specificParams
540
         */
541
        public MapserverLayer getSpecificParams() {
542
                return specificParams;
543
        }
544

    
545
        /**
546
         * @param specificParams the specificParams to set
547
         */
548
        public void setSpecificParams(MapserverLayer specificParams) {
549
                this.specificParams = specificParams;
550
        }
551
}