Statistics
| Revision:

svn-gvsig-desktop / branches / v10 / extensions / extPublishMapserver / src / org / gvsig / publish / mapserver / model / wms / MapserverWMSLayer.java @ 22616

History | View | Annotate | Download (17.4 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

    
48
import org.gvsig.publish.PublishLogger;
49
import org.gvsig.publish.exceptions.PublishException;
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.RemoteResource;
75

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

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

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

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

    
114

    
115
        /**
116
         * Initializes the remote resource name and title with the name and title of the layer
117
         */
118
        public void setLayerInfo(ILayerInfo layerInfo) {
119
                super.setLayerInfo(layerInfo);
120
                setName(getLayerInfo().getName());
121
                setTitle(getLayerInfo().getTitle());
122
                setAbstract("generated by gvSIG");
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

    
138
                if (getLayerInfo().getDataSource() != null){
139
                        config = new MapFile.Layer();
140
                        getMapfile().add(config);
141
                        generateLayerSection();
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
         */
179
        private void generateDataParameter(){
180
                IDataSourceInfo ds = getLayerInfo().getDataSource();
181
                if (ds.getType() == IDataSourceInfo.POSTGIS_TYPE){
182
                        IDataBaseInfo db = (IDataBaseInfo)ds;
183
                        String table = db.getTableName();
184
                        String schema = db.getSchemaName();
185
                        if (schema !=null){
186
                                table = schema+ "." + table;
187
                        }
188
                        config.data ="the_geom from "  + table + " using unique " + db.getGID() + " using srid=" + ds.getSRID(); 
189
                }else{
190
                        config.data = getService().getServer().getPublication().getServerSideFilePath(ds);
191
                }                                
192
        }
193

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

    
204
        /**
205
         * TODO:
206
         * lyr.labelsizeitem = getLayerInfo().getLabeling().getLabelHeightField();
207
         * lyr.labelangleitem = getLayerInfo().getLabeling().getLabelRotationField();
208
         *  
209
         */
210
        private void generateLabelingSection(){
211
                if (getLayerInfo().getLabeling() != null){
212
                        config.labelitem = getLayerInfo().getLabeling().getLabelField();                        
213
                }                
214
        }
215
        /**
216
         * Generates object MAP->LAYER->CLASS
217
         * @throws PublishException 
218
         * 
219
         */
220
        private void generateClassSection() throws PublishException{
221
                //CLASS
222
                Object source = getLayerInfo().getLegend();                
223
                if(source instanceof ISingleSymbolLegendInfo){
224
                        ISingleSymbolLegendInfo legend = (ISingleSymbolLegendInfo)source;
225
                        generateSingleLegend(legend, config);                
226
                }
227
                if(source instanceof IUniqueValuesLegendInfo){
228
                        IUniqueValuesLegendInfo legend = (IUniqueValuesLegendInfo)source;
229
                        generateUniqueLegend(legend, config);                        
230
                }
231
                if(source instanceof IIntervalLegendInfo){
232
                        IIntervalLegendInfo legend = (IIntervalLegendInfo)source;
233
                        generateIntervalLegend(legend, config);                        
234
                }
235
        }
236

    
237
        private void generateSingleLegend(ISingleSymbolLegendInfo legend, Layer lyr) throws PublishException{
238
                ISymbolInfo isymbol =  legend.getSymbolInfo();                
239
                lyr.classList.clear();
240
                MapClass clase = new MapClass();                
241
                //put name
242
                clase.name = "default";
243
                //put the size units
244
                lyr.sizeunits = isymbol.getUnits();
245

    
246
                generateStyle(isymbol, clase);
247
                //put labeling if exists
248
                if ( getLayerInfo().getLabeling().getLabelField() != null){
249
                        generateSymbol(getLayerInfo().getLabeling().getSymbolInfo(), clase);
250

    
251
                }
252
                //add the class into the layer
253
                lyr.addClass(clase);                
254
        }
255

    
256

    
257
        /**
258
         * Generate an interval legend
259
         * @param legend
260
         * The legend
261
         * @param lyr
262
         * The layer
263
         * @throws PublishException 
264
         * 
265
         * 
266
         */
267
        private void generateIntervalLegend(IIntervalLegendInfo legend, Layer lyr) throws PublishException{
268
                //check if is labeled
269
                boolean islabeled = false;
270
                if ( getLayerInfo().getLabeling().getLabelField() != null){
271
                        islabeled = true;
272
                }
273

    
274
                String[] expressions = legend.getExpressions();
275
                for (int i=0 ; i<expressions.length ; i++){
276
                        ISymbolInfo isymbol = legend.getSymbolByExpression(expressions[i]);
277
                        MapClass clase = new MapClass();
278
                        clase.name = isymbol.getTitle();
279
                        //TODO: change in infoProject
280
                        clase.expression = "(" + expressions[i] + ")";
281
                        generateStyle(isymbol, clase);
282
                        if (islabeled){
283
                                generateSymbol(getLayerInfo().getLabeling().getSymbolInfo(), clase);
284
                        }
285
                        lyr.addClass(clase);
286
                }
287
        }
288

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

    
315
        private void generateStyle(ISymbolInfo isymbol, MapClass clase) throws PublishException{                
316
                if (getLayerInfo().getDataSource().getDataType() == IDataSourceInfo.POINT_DATA){
317
                        //I can do a cast to Marker Symbol
318
                        IMarkerSymbolInfo pointSymbol = (IMarkerSymbolInfo)isymbol;
319
                        generateSymbol(pointSymbol, clase);
320
                }
321
                if (getLayerInfo().getDataSource().getDataType() == IDataSourceInfo.LINE_DATA){
322
                        //I can do a cast to Line Symbolizer
323
                        ILineSymbolInfo lineSymbol = (ILineSymbolInfo)isymbol;
324
                        generateSymbol(lineSymbol, clase);
325
                }        
326
                if (getLayerInfo().getDataSource().getDataType() == IDataSourceInfo.POLYGON_DATA){
327
                        //I can do a cast to Polygon Symbolizer
328
                        IFillSymbolInfo fillSymbol = (IFillSymbolInfo)isymbol;
329
                        generateSymbol(fillSymbol, clase);
330
                }
331

    
332
        }
333

    
334
        private void generateSymbol(ITextSymbolInfo textSymbol, MapClass clase){
335
                clase.etiqueta = new Label();
336
                //TODO: change by getColor()
337
                Color c = textSymbol.getFontColor();
338
                clase.etiqueta.color = new RGB(c.getRed(), c.getGreen(), c.getBlue());
339
                clase.etiqueta.angle = getLayerInfo().getLabeling().getLabelRotationField();
340
                clase.etiqueta.font = "vera";
341
                String hf = getLayerInfo().getLabeling().getLabelHeightField();
342
                if (hf ==null){
343
                        clase.etiqueta.size = new Double(textSymbol.getFontSize()).toString();
344
                }else{
345
                        clase.etiqueta.size = "[" + hf + "]";
346
                }
347
                clase.etiqueta.type = "truetype";
348
                if (!getLayerInfo().getLabeling().isVisibleFeatures()){
349
                        config.type ="ANNOTATION";
350
                }
351
        }
352

    
353
        private void generateSymbol(IMarkerSymbolInfo pointSymbol, MapClass clase) throws PublishException {
354
                clase.estilo = new StyleMap();                
355
                Color c = pointSymbol.getColor();
356
                clase.estilo.styleColor = new RGB(c.getRed(), c.getGreen(), c.getBlue());
357
                clase.estilo.size = pointSymbol.getSize();
358
                clase.symbol = pointSymbol.getWellKnowMarkerName();
359
                //if it's an image
360
                File icon = pointSymbol.getImageIconFile(); 
361
                if ( icon !=null){
362
                        clase.symbol = icon.getName();
363
                        Mapserver m = (Mapserver)getService().getServer();
364
                        String s = m.getMapfileFile().getParentFile().getAbsolutePath();
365
                        File dst = new File(s+ File.separator+ icon.getName());
366

    
367
                        try {
368
                                FileUtils.copy(icon, dst);
369
                        } catch (IOException e) {                        
370
                                throw new PublishException("cannot_copy_icons");                        
371
                        }
372
                }
373

    
374
        }
375
        /**
376
         * In Mapserver is impossible to have a dashed outline 
377
         * @param fillSymbol
378
         * @param clase
379
         */
380
        private void generateSymbol(IFillSymbolInfo fillSymbol, MapClass clase) {
381
                clase.estilo = new StyleMap();
382
                //set outline                
383
                ILineSymbolInfo linesymbolizer = fillSymbol.getOutline();
384
                Color c = linesymbolizer.getColor();
385
                clase.estilo.styleColorOutline = new RGB(c.getRed(), c.getGreen(), c.getBlue());
386
                clase.estilo.width = new Double(linesymbolizer.getLineWitdth()).intValue();                
387
                //set fill
388
                c = fillSymbol.getColor();
389
                clase.estilo.styleColor = new RGB(c.getRed(), c.getGreen(), c.getBlue());                                
390
                //if it is a well known polygon
391
                clase.symbol = fillSymbol.getWellKnowFillName();
392
        }
393

    
394
        private void generateSymbol(ILineSymbolInfo lineSymbol, MapClass clase) {
395
                Color c = lineSymbol.getColor();                
396
                clase.estilo = new StyleMap();
397
                clase.estilo.width = new Double(lineSymbol.getLineWitdth()).intValue();
398
                clase.estilo.styleColor = new RGB(c.getRed(), c.getGreen(), c.getBlue());
399
                //if it is a well know line
400
                clase.symbol = lineSymbol.getWellKnowLineName();
401
        }
402

    
403
        /**
404
         * Generates the METADATA object
405
         * @param mapLayer
406
         * 
407
         */
408
        private void generateMetadata(Layer mapLayer){
409
                //add metadata
410
                mapLayer.metadata.wms_name = getName();
411
                mapLayer.metadata.wms_title =getTitle();
412
                mapLayer.metadata.wms_abstract = getAbstract();
413
                Rectangle2D aux = getLayerInfo().getDataSource().getNativeBBox();
414
                String bbox = aux.getMinX() + " " + aux.getMinY() + " " + aux.getMaxX() + " " + aux.getMaxY();
415
                mapLayer.metadata.wms_extent = bbox;
416
                mapLayer.metadata.gml_include_items = "all";         
417
                //adding layer_group
418

    
419
                if (getLayerInfo().getPathString().equals("/")==false){
420
                        String aux2 = getLayerInfo().getPathString();
421
                        mapLayer.metadata.wms_layer_group = aux2.substring(0,aux2.length()-1);
422
                }
423
        }
424

    
425
        /*
426
         * (non-Javadoc)
427
         * @see com.iver.utiles.IPersistance#getClassName()
428
         */
429
        public String getClassName() {        
430
                return "MapserverWMSLayer";
431
        }
432
        /*
433
         * (non-Javadoc)
434
         * @see org.gvsig.publish.serversmodel.RemoteResource#getXMLEntity()
435
         */
436
        public XMLEntity getXMLEntity() {
437
                XMLEntity xml=super.getXMLEntity();
438
                //put version and name
439
                xml.setName(getClassName());
440
                xml.putProperty("version", getVersion());
441
                //put associations
442
                XMLEntity child = new XMLEntity();
443
                child.setName("ogcmetadata");
444
                child.addChild(ogcmetadata.getXMLEntity());
445
                xml.addChild(child);
446
                child = new XMLEntity();
447
                child.setName("mapserverlayer");
448
                child.addChild(specificParams.getXMLEntity());
449
                xml.addChild(child);        
450
                return xml;
451
        }
452
        /*
453
         * (non-Javadoc)
454
         * @see org.gvsig.publish.serversmodel.RemoteResource#setXMLEntity(com.iver.utiles.XMLEntity)
455
         */
456
        public void setXMLEntity(XMLEntity xml) {
457
                //check version
458
                int version = xml.getIntProperty("version");
459
                if (version != getVersion()){
460
                        PublishLogger.getLog().error("ERROR: " + getClassName() + ": the version doesn't match!");                        
461
                        return;
462
                }
463
                super.setXMLEntity(xml);                                                
464
                //set associations
465
                XMLEntity child = xml.firstChild("name","ogcmetadata");
466
                ogcmetadata.setXMLEntity(child.getChild(0));                
467
                child = xml.firstChild("name","mapserverlayer");
468
                specificParams.setXMLEntity(child.getChild(0));
469
        }
470

    
471
        /*
472
         * (non-Javadoc)
473
         * @see org.gvsig.publish.IPublishPersistence#getVersion()
474
         */
475
        public int getVersion() {                
476
                return 1;
477
        }
478
        /*
479
         * (non-Javadoc)
480
         * @see org.gvsig.publish.ogcmetadata.IOGCWMSLayerMetadata#isQueryable()
481
         */
482
        public boolean isQueryable() {
483
                return ogcmetadata.isQueryable();
484
        }
485
        /*
486
         * (non-Javadoc)
487
         * @see org.gvsig.publish.ogcmetadata.IOGCWMSLayerMetadata#setQueryable(boolean)
488
         */
489
        public void setQueryable(boolean queryable) {
490
                ogcmetadata.setQueryable(queryable);                
491
        }
492
        /*
493
         * (non-Javadoc)
494
         * @see org.gvsig.publish.ogcmetadata.IOGCCommonMetadata#getAbstract()
495
         */
496
        public String getAbstract() {                
497
                return ogcmetadata.getAbstract();
498
        }
499
        /*
500
         * (non-Javadoc)
501
         * @see org.gvsig.publish.ogcmetadata.IOGCCommonMetadata#getName()
502
         */
503
        public String getName() {                
504
                return ogcmetadata.getName();
505
        }
506
        /*
507
         * (non-Javadoc)
508
         * @see org.gvsig.publish.ogcmetadata.IOGCCommonMetadata#setAbstract(java.lang.String)
509
         */
510
        public void setAbstract(String description) {
511
                ogcmetadata.setAbstract(description);                
512
        }
513
        /*
514
         * (non-Javadoc)
515
         * @see org.gvsig.publish.ogcmetadata.IOGCCommonMetadata#setName(java.lang.String)
516
         */
517
        public void setName(String name) {
518
                ogcmetadata.setName(name);                
519
        }
520
        /*
521
         * (non-Javadoc)
522
         * @see org.gvsig.publish.ogcmetadata.IOGCCommonMetadata#setTitle(java.lang.String)
523
         */
524
        public void setTitle(String title) {
525
                ogcmetadata.setTitle(title);                
526
        }
527
        /*
528
         * (non-Javadoc)
529
         * @see org.gvsig.publish.ogcmetadata.IOGCCommonMetadata#getTitle()
530
         */
531
        public String getTitle() {                
532
                return ogcmetadata.getTitle();
533
        }
534

    
535
        /*
536
         * (non-Javadoc)
537
         * @see org.gvsig.publish.serversmodel.RemoteResource#getRegisterTag()
538
         */
539
        public String getRegisterTag() {                
540
                return REGISTER_TAG;
541
        }
542
        /*
543
         * (non-Javadoc)
544
         * @see java.lang.Object#toString()
545
         */
546
        public String toString(){
547
                return getName();
548
        }
549

    
550
        /**
551
         * @return the specificParams
552
         */
553
        public MapserverLayer getSpecificParams() {
554
                return specificParams;
555
        }
556

    
557
        /**
558
         * @param specificParams the specificParams to set
559
         */
560
        public void setSpecificParams(MapserverLayer specificParams) {
561
                this.specificParams = specificParams;
562
        }
563
}