@@ -103,7 +103,6 @@ bool QgsRequestHandler::headersSent() const
103
103
return mResponse .headersSent ();
104
104
}
105
105
106
-
107
106
void QgsRequestHandler::appendBody ( const QByteArray &body )
108
107
{
109
108
mResponse .write ( body );
@@ -152,62 +151,6 @@ QString QgsRequestHandler::formatToMimeType( const QString& format ) const
152
151
return format;
153
152
}
154
153
155
- void QgsRequestHandler::setGetMapResponse ( const QString& service, QImage* img, int imageQuality = -1 )
156
- {
157
- Q_UNUSED ( service );
158
- QgsMessageLog::logMessage ( QStringLiteral ( " setting getmap response..." ) );
159
- if ( img )
160
- {
161
- bool png16Bit = ( mFormatString .compare ( QLatin1String ( " image/png; mode=16bit" ), Qt::CaseInsensitive ) == 0 );
162
- bool png8Bit = ( mFormatString .compare ( QLatin1String ( " image/png; mode=8bit" ), Qt::CaseInsensitive ) == 0 );
163
- bool png1Bit = ( mFormatString .compare ( QLatin1String ( " image/png; mode=1bit" ), Qt::CaseInsensitive ) == 0 );
164
- if ( mFormat != QLatin1String ( " PNG" ) && mFormat != QLatin1String ( " JPG" ) && !png16Bit && !png8Bit && !png1Bit )
165
- {
166
- QgsMessageLog::logMessage ( QStringLiteral ( " service exception - incorrect image format requested..." ) );
167
- setServiceException ( QgsMapServiceException ( QStringLiteral ( " InvalidFormat" ), " Output format '" + mFormatString + " ' is not supported in the GetMap request" ) );
168
- return ;
169
- }
170
-
171
- // store the image in a QByteArray and set it directly
172
- QByteArray ba;
173
- QBuffer buffer ( &ba );
174
- buffer.open ( QIODevice::WriteOnly );
175
-
176
- // Do not use imageQuality for PNG images
177
- // For now, QImage expects quality to be a range 0-9 for PNG
178
- if ( mFormat == QLatin1String ( " PNG" ) )
179
- {
180
- imageQuality = -1 ;
181
- }
182
-
183
- if ( png8Bit )
184
- {
185
- QVector<QRgb> colorTable;
186
- medianCut ( colorTable, 256 , *img );
187
- QImage palettedImg = img->convertToFormat ( QImage::Format_Indexed8, colorTable, Qt::ColorOnly | Qt::ThresholdDither |
188
- Qt::ThresholdAlphaDither | Qt::NoOpaqueDetection );
189
- palettedImg.save ( &buffer, " PNG" , imageQuality );
190
- }
191
- else if ( png16Bit )
192
- {
193
- QImage palettedImg = img->convertToFormat ( QImage::Format_ARGB4444_Premultiplied );
194
- palettedImg.save ( &buffer, " PNG" , imageQuality );
195
- }
196
- else if ( png1Bit )
197
- {
198
- QImage palettedImg = img->convertToFormat ( QImage::Format_Mono, Qt::MonoOnly | Qt::ThresholdDither |
199
- Qt::ThresholdAlphaDither | Qt::NoOpaqueDetection );
200
- palettedImg.save ( &buffer, " PNG" , imageQuality );
201
- }
202
- else
203
- {
204
- img->save ( &buffer, mFormat .toUtf8 ().data (), imageQuality );
205
- }
206
-
207
- setHttpResponse ( ba, formatToMimeType ( mFormat ) );
208
- }
209
- }
210
-
211
154
void QgsRequestHandler::setGetCapabilitiesResponse ( const QDomDocument& doc )
212
155
{
213
156
QByteArray ba = doc.toByteArray ();
@@ -226,134 +169,6 @@ void QgsRequestHandler::setXmlResponse( const QDomDocument& doc, const QString&
226
169
setHttpResponse ( ba, mimeType );
227
170
}
228
171
229
- void QgsRequestHandler::setGetFeatureInfoResponse ( const QDomDocument& infoDoc, const QString& infoFormat )
230
- {
231
- QByteArray ba;
232
- QgsMessageLog::logMessage ( " Info format is:" + infoFormat );
233
-
234
- if ( infoFormat == QLatin1String ( " text/xml" ) || infoFormat.startsWith ( QLatin1String ( " application/vnd.ogc.gml" ) ) )
235
- {
236
- ba = infoDoc.toByteArray ();
237
- }
238
- else if ( infoFormat == QLatin1String ( " text/plain" ) || infoFormat == QLatin1String ( " text/html" ) )
239
- {
240
- // create string
241
- QString featureInfoString;
242
-
243
- if ( infoFormat == QLatin1String ( " text/plain" ) )
244
- {
245
- featureInfoString.append ( " GetFeatureInfo results\n " );
246
- featureInfoString.append ( " \n " );
247
- }
248
- else if ( infoFormat == QLatin1String ( " text/html" ) )
249
- {
250
- featureInfoString.append ( " <HEAD>\n " );
251
- featureInfoString.append ( " <TITLE> GetFeatureInfo results </TITLE>\n " );
252
- featureInfoString.append ( " <meta http-equiv=\" Content-Type\" content=\" text/html;charset=utf-8\" >\n " );
253
- featureInfoString.append ( " </HEAD>\n " );
254
- featureInfoString.append ( " <BODY>\n " );
255
- }
256
-
257
- QDomNodeList layerList = infoDoc.elementsByTagName ( QStringLiteral ( " Layer" ) );
258
-
259
- // layer loop
260
- for ( int i = 0 ; i < layerList.size (); ++i )
261
- {
262
- QDomElement layerElem = layerList.at ( i ).toElement ();
263
- if ( infoFormat == QLatin1String ( " text/plain" ) )
264
- {
265
- featureInfoString.append ( " Layer '" + layerElem.attribute ( QStringLiteral ( " name" ) ) + " '\n " );
266
- }
267
- else if ( infoFormat == QLatin1String ( " text/html" ) )
268
- {
269
- featureInfoString.append ( " <TABLE border=1 width=100%>\n " );
270
- featureInfoString.append ( " <TR><TH width=25%>Layer</TH><TD>" + layerElem.attribute ( QStringLiteral ( " name" ) ) + " </TD></TR>\n " );
271
- featureInfoString.append ( " </BR>" );
272
- }
273
-
274
- // feature loop (for vector layers)
275
- QDomNodeList featureNodeList = layerElem.elementsByTagName ( QStringLiteral ( " Feature" ) );
276
- QDomElement currentFeatureElement;
277
-
278
- if ( featureNodeList.size () < 1 ) // raster layer?
279
- {
280
- QDomNodeList attributeNodeList = layerElem.elementsByTagName ( QStringLiteral ( " Attribute" ) );
281
- for ( int j = 0 ; j < attributeNodeList.size (); ++j )
282
- {
283
- QDomElement attributeElement = attributeNodeList.at ( j ).toElement ();
284
- if ( infoFormat == QLatin1String ( " text/plain" ) )
285
- {
286
- featureInfoString.append ( attributeElement.attribute ( QStringLiteral ( " name" ) ) + " = '" +
287
- attributeElement.attribute ( QStringLiteral ( " value" ) ) + " '\n " );
288
- }
289
- else if ( infoFormat == QLatin1String ( " text/html" ) )
290
- {
291
- featureInfoString.append ( " <TR><TH>" + attributeElement.attribute ( QStringLiteral ( " name" ) ) + " </TH><TD>" +
292
- attributeElement.attribute ( QStringLiteral ( " value" ) ) + " </TD></TR>\n " );
293
- }
294
- }
295
- }
296
- else // vector layer
297
- {
298
- for ( int j = 0 ; j < featureNodeList.size (); ++j )
299
- {
300
- QDomElement featureElement = featureNodeList.at ( j ).toElement ();
301
- if ( infoFormat == QLatin1String ( " text/plain" ) )
302
- {
303
- featureInfoString.append ( " Feature " + featureElement.attribute ( QStringLiteral ( " id" ) ) + " \n " );
304
- }
305
- else if ( infoFormat == QLatin1String ( " text/html" ) )
306
- {
307
- featureInfoString.append ( " <TABLE border=1 width=100%>\n " );
308
- featureInfoString.append ( " <TR><TH>Feature</TH><TD>" + featureElement.attribute ( QStringLiteral ( " id" ) ) + " </TD></TR>\n " );
309
- }
310
- // attribute loop
311
- QDomNodeList attributeNodeList = featureElement.elementsByTagName ( QStringLiteral ( " Attribute" ) );
312
- for ( int k = 0 ; k < attributeNodeList.size (); ++k )
313
- {
314
- QDomElement attributeElement = attributeNodeList.at ( k ).toElement ();
315
- if ( infoFormat == QLatin1String ( " text/plain" ) )
316
- {
317
- featureInfoString.append ( attributeElement.attribute ( QStringLiteral ( " name" ) ) + " = '" +
318
- attributeElement.attribute ( QStringLiteral ( " value" ) ) + " '\n " );
319
- }
320
- else if ( infoFormat == QLatin1String ( " text/html" ) )
321
- {
322
- featureInfoString.append ( " <TR><TH>" + attributeElement.attribute ( QStringLiteral ( " name" ) ) + " </TH><TD>" + attributeElement.attribute ( QStringLiteral ( " value" ) ) + " </TD></TR>\n " );
323
- }
324
- }
325
-
326
- if ( infoFormat == QLatin1String ( " text/html" ) )
327
- {
328
- featureInfoString.append ( " </TABLE>\n </BR>\n " );
329
- }
330
- }
331
- }
332
- if ( infoFormat == QLatin1String ( " text/plain" ) )
333
- {
334
- featureInfoString.append ( " \n " );
335
- }
336
- else if ( infoFormat == QLatin1String ( " text/html" ) )
337
- {
338
- featureInfoString.append ( " </TABLE>\n <BR></BR>\n " );
339
-
340
- }
341
- }
342
- if ( infoFormat == QLatin1String ( " text/html" ) )
343
- {
344
- featureInfoString.append ( " </BODY>\n " );
345
- }
346
- ba = featureInfoString.toUtf8 ();
347
- }
348
- else // unsupported format, set exception
349
- {
350
- setServiceException ( QgsMapServiceException ( QStringLiteral ( " InvalidFormat" ), " Feature info format '" + infoFormat + " ' is not supported. Possibilities are 'text/plain', 'text/html' or 'text/xml'." ) );
351
- return ;
352
- }
353
-
354
- setHttpResponse ( ba, infoFormat );
355
- }
356
-
357
172
void QgsRequestHandler::setServiceException ( const QgsMapServiceException& ex )
358
173
{
359
174
// Safety measure to avoid potential leaks if called repeatedly
@@ -378,15 +193,6 @@ void QgsRequestHandler::setServiceException( const QgsMapServiceException& ex )
378
193
setHttpResponse ( ba, QStringLiteral ( " text/xml" ) );
379
194
}
380
195
381
- void QgsRequestHandler::setGetPrintResponse ( QByteArray* ba )
382
- {
383
- if ( ba )
384
- {
385
- setHttpResponse ( *ba, formatToMimeType ( mFormat ) );
386
- }
387
- }
388
-
389
-
390
196
bool QgsRequestHandler::startGetFeatureResponse ( QByteArray* ba, const QString& infoFormat )
391
197
{
392
198
if ( !ba )
@@ -608,296 +414,3 @@ void QgsRequestHandler::removeParameter( const QString &key )
608
414
}
609
415
610
416
611
- void QgsRequestHandler::medianCut ( QVector<QRgb>& colorTable, int nColors, const QImage& inputImage )
612
- {
613
- QHash<QRgb, int > inputColors;
614
- imageColors ( inputColors, inputImage );
615
-
616
- if ( inputColors.size () <= nColors ) // all the colors in the image can be mapped to one palette color
617
- {
618
- colorTable.resize ( inputColors.size () );
619
- int index = 0 ;
620
- QHash<QRgb, int >::const_iterator inputColorIt = inputColors.constBegin ();
621
- for ( ; inputColorIt != inputColors.constEnd (); ++inputColorIt )
622
- {
623
- colorTable[index] = inputColorIt.key ();
624
- ++index;
625
- }
626
- return ;
627
- }
628
-
629
- // create first box
630
- QgsColorBox firstBox; // QList< QPair<QRgb, int> >
631
- int firstBoxPixelSum = 0 ;
632
- QHash<QRgb, int >::const_iterator inputColorIt = inputColors.constBegin ();
633
- for ( ; inputColorIt != inputColors.constEnd (); ++inputColorIt )
634
- {
635
- firstBox.push_back ( qMakePair ( inputColorIt.key (), inputColorIt.value () ) );
636
- firstBoxPixelSum += inputColorIt.value ();
637
- }
638
-
639
- QgsColorBoxMap colorBoxMap; // QMultiMap< int, ColorBox >
640
- colorBoxMap.insert ( firstBoxPixelSum, firstBox );
641
- QMap<int , QgsColorBox>::iterator colorBoxMapIt = colorBoxMap.end ();
642
-
643
- // split boxes until number of boxes == nColors or all the boxes have color count 1
644
- bool allColorsMapped = false ;
645
- while ( colorBoxMap.size () < nColors )
646
- {
647
- // start at the end of colorBoxMap and pick the first entry with number of colors < 1
648
- colorBoxMapIt = colorBoxMap.end ();
649
- while ( true )
650
- {
651
- --colorBoxMapIt;
652
- if ( colorBoxMapIt.value ().size () > 1 )
653
- {
654
- splitColorBox ( colorBoxMapIt.value (), colorBoxMap, colorBoxMapIt );
655
- break ;
656
- }
657
- if ( colorBoxMapIt == colorBoxMap.begin () )
658
- {
659
- allColorsMapped = true ;
660
- break ;
661
- }
662
- }
663
-
664
- if ( allColorsMapped )
665
- {
666
- break ;
667
- }
668
- else
669
- {
670
- continue ;
671
- }
672
- }
673
-
674
- // get representative colors for the boxes
675
- int index = 0 ;
676
- colorTable.resize ( colorBoxMap.size () );
677
- QgsColorBoxMap::const_iterator colorBoxIt = colorBoxMap.constBegin ();
678
- for ( ; colorBoxIt != colorBoxMap.constEnd (); ++colorBoxIt )
679
- {
680
- colorTable[index] = boxColor ( colorBoxIt.value (), colorBoxIt.key () );
681
- ++index;
682
- }
683
- }
684
-
685
- void QgsRequestHandler::imageColors ( QHash<QRgb, int >& colors, const QImage& image )
686
- {
687
- colors.clear ();
688
- int width = image.width ();
689
- int height = image.height ();
690
-
691
- const QRgb* currentScanLine = nullptr ;
692
- QHash<QRgb, int >::iterator colorIt;
693
- for ( int i = 0 ; i < height; ++i )
694
- {
695
- currentScanLine = ( const QRgb* )( image.scanLine ( i ) );
696
- for ( int j = 0 ; j < width; ++j )
697
- {
698
- colorIt = colors.find ( currentScanLine[j] );
699
- if ( colorIt == colors.end () )
700
- {
701
- colors.insert ( currentScanLine[j], 1 );
702
- }
703
- else
704
- {
705
- colorIt.value ()++;
706
- }
707
- }
708
- }
709
- }
710
-
711
- void QgsRequestHandler::splitColorBox ( QgsColorBox& colorBox, QgsColorBoxMap& colorBoxMap,
712
- QMap<int , QgsColorBox>::iterator colorBoxMapIt )
713
- {
714
-
715
- if ( colorBox.size () < 2 )
716
- {
717
- return ; // need at least two colors for a split
718
- }
719
-
720
- // a,r,g,b ranges
721
- int redRange = 0 ;
722
- int greenRange = 0 ;
723
- int blueRange = 0 ;
724
- int alphaRange = 0 ;
725
-
726
- if ( !minMaxRange ( colorBox, redRange, greenRange, blueRange, alphaRange ) )
727
- {
728
- return ;
729
- }
730
-
731
- // sort color box for a/r/g/b
732
- if ( redRange >= greenRange && redRange >= blueRange && redRange >= alphaRange )
733
- {
734
- qSort ( colorBox.begin (), colorBox.end (), redCompare );
735
- }
736
- else if ( greenRange >= redRange && greenRange >= blueRange && greenRange >= alphaRange )
737
- {
738
- qSort ( colorBox.begin (), colorBox.end (), greenCompare );
739
- }
740
- else if ( blueRange >= redRange && blueRange >= greenRange && blueRange >= alphaRange )
741
- {
742
- qSort ( colorBox.begin (), colorBox.end (), blueCompare );
743
- }
744
- else
745
- {
746
- qSort ( colorBox.begin (), colorBox.end (), alphaCompare );
747
- }
748
-
749
- // get median
750
- double halfSum = colorBoxMapIt.key () / 2.0 ;
751
- int currentSum = 0 ;
752
- int currentListIndex = 0 ;
753
-
754
- QgsColorBox::iterator colorBoxIt = colorBox.begin ();
755
- for ( ; colorBoxIt != colorBox.end (); ++colorBoxIt )
756
- {
757
- currentSum += colorBoxIt->second ;
758
- if ( currentSum >= halfSum )
759
- {
760
- break ;
761
- }
762
- ++currentListIndex;
763
- }
764
-
765
- if ( currentListIndex > ( colorBox.size () - 2 ) ) // if the median is contained in the last color, split one item before that
766
- {
767
- --currentListIndex;
768
- currentSum -= colorBoxIt->second ;
769
- }
770
- else
771
- {
772
- ++colorBoxIt; // the iterator needs to point behind the last item to remove
773
- }
774
-
775
- // do split: replace old color box, insert new one
776
- QgsColorBox newColorBox1 = colorBox.mid ( 0 , currentListIndex + 1 );
777
- colorBoxMap.insert ( currentSum, newColorBox1 );
778
-
779
- colorBox.erase ( colorBox.begin (), colorBoxIt );
780
- QgsColorBox newColorBox2 = colorBox;
781
- colorBoxMap.erase ( colorBoxMapIt );
782
- colorBoxMap.insert ( halfSum * 2.0 - currentSum, newColorBox2 );
783
- }
784
-
785
- bool QgsRequestHandler::minMaxRange ( const QgsColorBox& colorBox, int & redRange, int & greenRange, int & blueRange, int & alphaRange )
786
- {
787
- if ( colorBox.size () < 1 )
788
- {
789
- return false ;
790
- }
791
-
792
- int rMin = INT_MAX;
793
- int gMin = INT_MAX;
794
- int bMin = INT_MAX;
795
- int aMin = INT_MAX;
796
- int rMax = INT_MIN;
797
- int gMax = INT_MIN;
798
- int bMax = INT_MIN;
799
- int aMax = INT_MIN;
800
-
801
- int currentRed = 0 ;
802
- int currentGreen = 0 ;
803
- int currentBlue = 0 ;
804
- int currentAlpha = 0 ;
805
-
806
- QgsColorBox::const_iterator colorBoxIt = colorBox.constBegin ();
807
- for ( ; colorBoxIt != colorBox.constEnd (); ++colorBoxIt )
808
- {
809
- currentRed = qRed ( colorBoxIt->first );
810
- if ( currentRed > rMax )
811
- {
812
- rMax = currentRed;
813
- }
814
- if ( currentRed < rMin )
815
- {
816
- rMin = currentRed;
817
- }
818
-
819
- currentGreen = qGreen ( colorBoxIt->first );
820
- if ( currentGreen > gMax )
821
- {
822
- gMax = currentGreen;
823
- }
824
- if ( currentGreen < gMin )
825
- {
826
- gMin = currentGreen;
827
- }
828
-
829
- currentBlue = qBlue ( colorBoxIt->first );
830
- if ( currentBlue > bMax )
831
- {
832
- bMax = currentBlue;
833
- }
834
- if ( currentBlue < bMin )
835
- {
836
- bMin = currentBlue;
837
- }
838
-
839
- currentAlpha = qAlpha ( colorBoxIt->first );
840
- if ( currentAlpha > aMax )
841
- {
842
- aMax = currentAlpha;
843
- }
844
- if ( currentAlpha < aMin )
845
- {
846
- aMin = currentAlpha;
847
- }
848
- }
849
-
850
- redRange = rMax - rMin;
851
- greenRange = gMax - gMin ;
852
- blueRange = bMax - bMin;
853
- alphaRange = aMax - aMin;
854
- return true ;
855
- }
856
-
857
- bool QgsRequestHandler::redCompare ( QPair<QRgb, int > c1, QPair<QRgb, int > c2 )
858
- {
859
- return qRed ( c1.first ) < qRed ( c2.first );
860
- }
861
-
862
- bool QgsRequestHandler::greenCompare ( QPair<QRgb, int > c1, QPair<QRgb, int > c2 )
863
- {
864
- return qGreen ( c1.first ) < qGreen ( c2.first );
865
- }
866
-
867
- bool QgsRequestHandler::blueCompare ( QPair<QRgb, int > c1, QPair<QRgb, int > c2 )
868
- {
869
- return qBlue ( c1.first ) < qBlue ( c2.first );
870
- }
871
-
872
- bool QgsRequestHandler::alphaCompare ( QPair<QRgb, int > c1, QPair<QRgb, int > c2 )
873
- {
874
- return qAlpha ( c1.first ) < qAlpha ( c2.first );
875
- }
876
-
877
- QRgb QgsRequestHandler::boxColor ( const QgsColorBox& box, int boxPixels )
878
- {
879
- double avRed = 0 ;
880
- double avGreen = 0 ;
881
- double avBlue = 0 ;
882
- double avAlpha = 0 ;
883
- QRgb currentColor;
884
- int currentPixel;
885
-
886
- double weight;
887
-
888
- QgsColorBox::const_iterator colorBoxIt = box.constBegin ();
889
- for ( ; colorBoxIt != box.constEnd (); ++colorBoxIt )
890
- {
891
- currentColor = colorBoxIt->first ;
892
- currentPixel = colorBoxIt->second ;
893
- weight = ( double )currentPixel / boxPixels;
894
- avRed += ( qRed ( currentColor ) * weight );
895
- avGreen += ( qGreen ( currentColor ) * weight );
896
- avBlue += ( qBlue ( currentColor ) * weight );
897
- avAlpha += ( qAlpha ( currentColor ) * weight );
898
- }
899
-
900
- return qRgba ( avRed, avGreen, avBlue, avAlpha );
901
- }
902
-
903
-
0 commit comments