~ubuntu-branches/ubuntu/wily/qgis/wily

« back to all changes in this revision

Viewing changes to src/gui/qgsmapserverexport.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Johan Van de Wauw
  • Date: 2010-07-11 20:23:24 UTC
  • mfrom: (3.1.4 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100711202324-5ktghxa7hracohmr
Tags: 1.4.0+12730-3ubuntu1
* Merge from Debian unstable (LP: #540941).
* Fix compilation issues with QT 4.7
* Add build-depends on libqt4-webkit-dev 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
  qgsmapserverexport.cpp - Export QGIS MapCanvas to MapServer
3
 
  --------------------------------------
4
 
Date                 : 8-Nov-2003
5
 
Copyright            : (C) 2003 by Gary E.Sherman
6
 
email                : sherman at mrcc.com
7
 
 ***************************************************************************
8
 
 *                                                                         *
9
 
 *   This program is free software; you can redistribute it and/or modify  *
10
 
 *   it under the terms of the GNU General Public License as published by  *
11
 
 *   the Free Software Foundation; either version 2 of the License, or     *
12
 
 *   (at your option) any later version.                                   *
13
 
 *                                                                         *
14
 
 ***************************************************************************/
15
 
/* $Id: qgsmapserverexport.cpp 6816 2007-03-18 11:43:41Z homann $ */
16
 
 
17
 
#include "qgsmapserverexport.h"
18
 
 
19
 
#include "qgis.h"
20
 
#include "qgsdatasourceuri.h"
21
 
#include "qgshelpviewer.h"
22
 
#include "qgsmapcanvas.h"
23
 
#include "qgsmaplayer.h"
24
 
#include "qgsrect.h"
25
 
#include "qgsvectorlayer.h"
26
 
#include "qgsvectordataprovider.h"
27
 
 
28
 
#include <QFileDialog>
29
 
#include <QFileInfo>
30
 
#include <QMessageBox>
31
 
 
32
 
#include <iostream>
33
 
#include <fstream>
34
 
 
35
 
// constructor
36
 
QgsMapserverExport::QgsMapserverExport(QgsMapCanvas * _map, QWidget * parent, Qt::WFlags fl)
37
 
  : QDialog(parent, fl), map(_map)
38
 
{
39
 
  setupUi(this);
40
 
  connect(buttonOk, SIGNAL(clicked()), this, SLOT(accept()));
41
 
  connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
42
 
  // These values shouldn't be translated, the units should be in english in the map file
43
 
  // Qt designer adds translate() by default
44
 
  cmbMapUnits->addItem(QString::fromUtf8("dd"));
45
 
  cmbMapUnits->addItem(QString::fromUtf8("feet"));
46
 
  cmbMapUnits->addItem(QString::fromUtf8("meters"));
47
 
  cmbMapUnits->addItem(QString::fromUtf8("miles"));
48
 
  cmbMapUnits->addItem(QString::fromUtf8("inches"));
49
 
  cmbMapUnits->addItem(QString::fromUtf8("kilometers"));
50
 
}
51
 
 
52
 
// Default destructor
53
 
QgsMapserverExport::~QgsMapserverExport()
54
 
{
55
 
}
56
 
 
57
 
// Get the base name for the map file
58
 
QString QgsMapserverExport::baseName()
59
 
{
60
 
  QFileInfo fi(txtMapFilePath->text());
61
 
  return fi.baseName(true);
62
 
}
63
 
 
64
 
// Write the map file
65
 
bool QgsMapserverExport::write()
66
 
{
67
 
 
68
 
  //QMessageBox::information(0,"Full Path",fullPath);
69
 
  int okToSave = 0;
70
 
  // Check for file and prompt for overwrite if it exists
71
 
  if (QFile::exists(txtMapFilePath->text()))
72
 
  {
73
 
    okToSave = QMessageBox::warning(0, tr("Overwrite File?"), txtMapFilePath->text() +
74
 
        tr(" exists. \nDo you want to overwrite it?"), tr("Yes"), tr("No"));
75
 
  }
76
 
  if (okToSave == 0)
77
 
  {
78
 
    // write the project information to the selected file
79
 
    writeMapFile();
80
 
    return true;
81
 
  } else
82
 
  {
83
 
    return false;
84
 
  }
85
 
}
86
 
 
87
 
 
88
 
void QgsMapserverExport::setFileName(QString fn)
89
 
{
90
 
  fullPath = fn;
91
 
}
92
 
 
93
 
QString QgsMapserverExport::fullPathName()
94
 
{
95
 
  return fullPath;
96
 
}
97
 
 
98
 
void QgsMapserverExport::writeMapFile()
99
 
{
100
 
  // write the map file, making massive assumptions about default values
101
 
#ifdef QGISDEBUG
102
 
  std::cout << "Opening map file " << txtMapFilePath->text().toLocal8Bit().data() << std::endl;
103
 
#endif
104
 
  std::ofstream mapFile(txtMapFilePath->text().toLocal8Bit().data());
105
 
  if (!mapFile.fail())
106
 
  {
107
 
    // XXX So, what encoding should we use here???
108
 
    mapFile << "# Map file generated by QGIS version " << QGis::qgisVersion << std::endl;
109
 
    mapFile << "# Edit this file to customize for your interface" << std::endl;
110
 
    mapFile << "# Not all sections are complete. See comments for details." << std::endl;
111
 
    if (!chkExpLayersOnly->isChecked())
112
 
    {
113
 
      // header
114
 
      mapFile << "NAME " << txtMapName->text().toLocal8Bit().data() << std::endl;
115
 
      mapFile << "STATUS ON" << std::endl;
116
 
      mapFile << "\n# Map image size. Change size as desired" << std::endl;
117
 
      mapFile << "SIZE " << txtMapWidth->text().toLocal8Bit().data() << " " << txtMapHeight->text().toLocal8Bit().data() << std::endl;
118
 
      // web interface definition - this is minimal!
119
 
      mapFile << "#" << std::endl;
120
 
      mapFile << "# Start of web interface definition. Only the TEMPLATE parameter" << std::endl;
121
 
      mapFile << "# must be specified to display a map. See Mapserver documentation" << std::endl;
122
 
      mapFile << "#" << std::endl;
123
 
      mapFile << "WEB" << std::endl;
124
 
      // if no header is supplied, write the header line but comment it out
125
 
      if (txtWebHeader->text().isEmpty())
126
 
      {
127
 
        mapFile << "  # HEADER" << std::endl;
128
 
      } else
129
 
      {
130
 
        // header provided - write it
131
 
        mapFile << "  HEADER " << txtWebHeader->text().toLocal8Bit().data() << std::endl;
132
 
      }
133
 
      // if no template provided, write the template line but comment it out
134
 
      if (txtWebTemplate->text().isEmpty())
135
 
      {
136
 
        mapFile << "  # TEMPLATE" << std::endl;
137
 
      } else
138
 
      {
139
 
        // template provided - write it
140
 
        mapFile << "  TEMPLATE " << txtWebTemplate->text().toLocal8Bit().data() << std::endl;
141
 
      }
142
 
      // if no footer provided, write the footer line but comment it out
143
 
      if (txtWebFooter->text().isEmpty())
144
 
      {
145
 
        mapFile << "  # FOOTER" << std::endl;
146
 
      } else
147
 
      {
148
 
        mapFile << "  FOOTER " << txtWebFooter->text().toLocal8Bit().data() << std::endl;
149
 
      }
150
 
      QString minScale = txtMinScale->text().isEmpty()?"#MINSCALE":"MINSCALE";
151
 
      QString maxScale = txtMinScale->text().isEmpty()?"  #MAXSCALE ":"  MAXSCALE ";
152
 
      // write min and maxscale
153
 
      mapFile << minScale.toLocal8Bit().data() << txtMinScale->text().toLocal8Bit().data() << std::endl;
154
 
      mapFile << maxScale.toLocal8Bit().data() << txtMaxScale->text().toLocal8Bit().data() << std::endl;
155
 
      // write comments about the imagepath and image url
156
 
      mapFile << "# Set IMAGEPATH to the path where mapserver should\n" <<
157
 
        "# write its output\n" <<
158
 
        " IMAGEPATH '/tmp/'" << std::endl; 
159
 
      mapFile << "# Set IMAGEURL to the url that points to IMAGEPATH" << std::endl; 
160
 
      mapFile << " #IMAGEURL '/map_output/'" << std::endl; 
161
 
      // end of web section
162
 
      mapFile << "END" << std::endl;
163
 
 
164
 
      // extent
165
 
      mapFile << "\n# Extent based on full extent of QGIS view" << std::endl;
166
 
      mapFile << "EXTENT ";
167
 
      QgsRect extent = map->extent();
168
 
      mapFile << extent.xMin() << " " << extent.yMin() << " ";
169
 
      mapFile << extent.xMax() << " " << extent.yMax() << std::endl;
170
 
      // units
171
 
      mapFile << "UNITS " << cmbMapUnits->currentText().toLocal8Bit().data() << std::endl;
172
 
      // image info
173
 
      mapFile << "IMAGECOLOR 255 255 255" << std::endl;
174
 
      mapFile << "IMAGETYPE " << cmbMapImageType->currentText().toLocal8Bit().data() << std::endl;
175
 
      // projection information TODO: support projections :)
176
 
      mapFile << "# Projection definition" << std::endl;
177
 
      mapFile << "# Projections are not currenlty supported. If desired, add your own" << std::endl;
178
 
      mapFile << "# projection information based on Mapserver documentation." << std::endl;
179
 
      mapFile << "#" << std::endl;
180
 
 
181
 
    } else
182
 
    {
183
 
      mapFile << " # This file contains layer definitions only and is not a complete" << std::endl;
184
 
      mapFile << " # Mapserver map file." << std::endl;
185
 
    }
186
 
 
187
 
    // write layer definitions 
188
 
    for (int i = 0; i < map->layerCount(); i++)
189
 
    {
190
 
      bool isPolygon = false;
191
 
      bool isLine = false;
192
 
      QgsMapLayer *lyr = map->getZpos(i);
193
 
#ifdef QGISDEBUG
194
 
      std::cout << "Mapsrver Export Processing Layer" << std::endl;
195
 
#endif
196
 
      mapFile << "LAYER" << std::endl;
197
 
      QString name = lyr->name().lower();
198
 
      // MapServer NAME must be < 20 char and unique
199
 
      name.replace(QRegExp(" "), "_");
200
 
      name.replace(QRegExp("\\."), "_");
201
 
      name.replace(QRegExp("\\("), "_");
202
 
      name.replace(QRegExp("\\)"), "_");
203
 
      mapFile << "  NAME " << name.toLocal8Bit().data() << std::endl;
204
 
      // feature type
205
 
#ifdef QGISDEBUG
206
 
      std::cout << "\tMapserver Export checking feature type" << std::endl;
207
 
#endif
208
 
      mapFile << "  TYPE ";
209
 
      switch (lyr->featureType())
210
 
      {
211
 
        case QGis::WKBPoint:
212
 
        case QGis::WKBMultiPoint:
213
 
          mapFile << "POINT";
214
 
          break;
215
 
        case QGis::WKBLineString:
216
 
        case QGis::WKBMultiLineString:
217
 
          mapFile << "LINE";
218
 
          isLine = true;
219
 
          break;
220
 
        case QGis::WKBPolygon:
221
 
        case QGis::WKBMultiPolygon:
222
 
          mapFile << "POLYGON";
223
 
          isPolygon = true;
224
 
          break;
225
 
                 
226
 
      }
227
 
      if(lyr->type() == QgsMapLayer::RASTER)
228
 
      {
229
 
        mapFile << "RASTER";
230
 
      }
231
 
      mapFile << std::endl;
232
 
 
233
 
#ifdef QGISDEBUG
234
 
      std::cout << "\tMapserver Export checking visibility" << std::endl;
235
 
#endif
236
 
      // set visibility (STATUS)
237
 
      mapFile << "  STATUS ";
238
 
      if (lyr->visible())
239
 
      {
240
 
        mapFile << "ON";
241
 
      } else
242
 
      {
243
 
        mapFile << "OFF";
244
 
      }
245
 
      mapFile << std::endl;
246
 
 
247
 
      // data source (DATA)
248
 
      // Data source spec depends on layer type
249
 
#ifdef QGISDEBUG
250
 
      std::cout << "\tMapserver Export checking layer type" << std::endl;
251
 
#endif
252
 
      switch (lyr->type())
253
 
      {
254
 
        case QgsMapLayer::VECTOR:
255
 
          // get the provider type
256
 
          {
257
 
            QString providerType = 
258
 
              dynamic_cast<QgsVectorLayer*>(lyr)->providerType();
259
 
            if(providerType == "postgres")
260
 
            {
261
 
              QgsDataSourceURI *dUri = 
262
 
                dynamic_cast<QgsVectorLayer *>(lyr)->getDataProvider()->getURI();
263
 
              mapFile << "CONNECTION \"user=" << dUri->username.toLocal8Bit().data();
264
 
              if(dUri->password.length() > 0)
265
 
              {
266
 
                mapFile << " password="<< dUri->password.toLocal8Bit().data();
267
 
              }
268
 
              mapFile  << " dbname=" << dUri->database.toLocal8Bit().data() 
269
 
                << " host=" << dUri->host.toLocal8Bit().data()
270
 
                << " port=" << dUri->port.toLocal8Bit().data()
271
 
                << "\"" << std::endl; 
272
 
              mapFile << "CONNECTIONTYPE postgis" << std::endl; 
273
 
              mapFile << "DATA \"" << dUri->geometryColumn.toLocal8Bit().data() << " from " 
274
 
                << dUri->table.toLocal8Bit().data() << "\"" << std::endl; 
275
 
              if(dUri->sql.length() > 0)
276
 
              {
277
 
                mapFile << "FILTER \"" << dUri->sql.toLocal8Bit().data() << "\"" << std::endl; 
278
 
              }
279
 
 
280
 
            }
281
 
            else
282
 
            {
283
 
 
284
 
              // must be an ogr 
285
 
              mapFile << "  DATA " << lyr->source().toLocal8Bit().data() << std::endl;
286
 
            }
287
 
          }
288
 
          break;
289
 
        case QgsMapLayer::RASTER:
290
 
          mapFile << "  DATA " << lyr->source().toLocal8Bit().data() << std::endl; 
291
 
          
292
 
          break;
293
 
      }
294
 
#ifdef QGISDEBUG
295
 
      std::cout << "\tMapserver Export creating symbol entries" << std::endl;
296
 
#endif
297
 
      // create a simple class entry based on red fill color and black outline color
298
 
      //TODO: adapt the following section to the new symbology
299
 
 
300
 
      mapFile << "  CLASS" << std::endl;
301
 
      //QListViewItem *li = map->getLegend()->currentItem();
302
 
      //    return li->text(0);
303
 
#ifdef QGISDEBUG
304
 
      std::cout << "\tMapserver Export symbol name" << std::endl;
305
 
#endif
306
 
      mapFile << "    NAME \"" << lyr->name().toLocal8Bit().data() << "\"" << std::endl;
307
 
      mapFile << "    # TEMPLATE" << std::endl;
308
 
      if (isPolygon)
309
 
      {
310
 
#ifdef QGISDEBUG
311
 
        std::cout << "\tMapserver Export symbol fill color" << std::endl;
312
 
#endif
313
 
        // use random fill colors
314
 
        // TODO Get fill color from the renderer
315
 
        // TODO Figure out what to do for layers that are
316
 
        //      rendered with other than the simple symbol
317
 
        //      renderer.
318
 
        int red = 1 + (int) (255.0 * rand() / (RAND_MAX + 1.0));
319
 
        int green = 1 + (int) (255.0 * rand() / (RAND_MAX + 1.0));
320
 
        int blue = 1 + (int) (255.0 * rand() / (RAND_MAX + 1.0));
321
 
 
322
 
        mapFile << "    COLOR " << red << " " << green << " " << blue << std::endl;
323
 
      }
324
 
#ifdef QGISDEBUG
325
 
      std::cout << "\tMapserver Export checking for line symbol " << std::endl;
326
 
#endif
327
 
      if (isPolygon || isLine)
328
 
      {
329
 
        // use line color
330
 
        // TODO Get line color from the renderer
331
 
        int red = 1 + (int) (255.0 * rand() / (RAND_MAX + 1.0));
332
 
        int green = 1 + (int) (255.0 * rand() / (RAND_MAX + 1.0));
333
 
        int blue = 1 + (int) (255.0 * rand() / (RAND_MAX + 1.0));
334
 
        mapFile << "    OUTLINECOLOR " << red << " "
335
 
          << green << " " << blue << std::endl;
336
 
      }
337
 
      mapFile << "  END" << std::endl;
338
 
      mapFile << "END" << std::endl;
339
 
#ifdef QGISDEBUG
340
 
      std::cout << "\tMapserver Export layer definition done..." << std::endl;
341
 
#endif
342
 
    }
343
 
    if (!chkExpLayersOnly->isChecked())
344
 
    {
345
 
      mapFile << "END # Map File";
346
 
    }
347
 
    mapFile.flush();
348
 
    mapFile.close();
349
 
  } else
350
 
  {
351
 
  }
352
 
}
353
 
 
354
 
void QgsMapserverExport::on_chkExpLayersOnly_clicked()
355
 
{
356
 
  // disable inputs if only layer objects are being written
357
 
  grpMap->setEnabled(!chkExpLayersOnly->isChecked());
358
 
  grpWeb->setEnabled(!chkExpLayersOnly->isChecked());
359
 
}
360
 
 
361
 
void QgsMapserverExport::on_btnChooseFile_clicked()
362
 
{
363
 
  QString s = QFileDialog::getSaveFileName(
364
 
                    this,
365
 
                    tr("Choose a filename for the exported map file"),
366
 
                    "./",
367
 
                    tr("Mapserver files (*.map)" ) );
368
 
  txtMapFilePath->setText(s);
369
 
}
370
 
 
371
 
void QgsMapserverExport::on_buttonHelp_clicked()
372
 
{
373
 
  //QMessageBox::information(this, "Help","Help");
374
 
  QgsHelpViewer *hv = new QgsHelpViewer(this);
375
 
  // causes problems in qt3.1.x:  hv->setModal(false);
376
 
  hv->setCaption( tr("QGIS Help - Mapserver Export") );
377
 
  hv->show();
378
 
}