21 #ifndef otbMapFileProductWriter_hxx
22 #define otbMapFileProductWriter_hxx
25 #include "itksys/SystemTools.hxx"
34 template <
class TInputImage>
37 m_GenericRSResampler = GenericRSResamplerType::New();
44 this->SetNumberOfRequiredInputs(1);
51 template <
class TInputImage>
59 template <
class TInputImage>
63 this->ProcessObject::SetNthInput(0,
const_cast<InputImageType*
>(input));
67 template <
class TInputImage>
71 this->ProcessObject::SetNthInput(index,
const_cast<TInputImage*
>(image));
77 template <
class TInputImage>
80 if (this->GetNumberOfInputs() < 1)
85 return static_cast<const TInputImage*
>(this->ProcessObject::GetInput(0));
91 template <
class TInputImage>
94 return static_cast<const TInputImage*
>(this->ProcessObject::GetInput(idx));
102 template <
class TInputImage>
106 m_VectorImage =
const_cast<TInputImage*
>(this->GetInput());
107 m_VectorImage->UpdateOutputInformation();
110 if (!m_VectorImage->GetImageMetadata().HasSensorGeometry()
111 && m_VectorImage->GetImageMetadata().HasSensorGeometry())
113 otbMsgDevMacro(
"Sensor Model detected : Reprojecting in the target SRID");
114 m_GenericRSResampler->SetInput(this->GetInput());
116 m_VectorImage = m_GenericRSResampler->GetOutput();
117 m_VectorImage->UpdateOutputInformation();
124 this->GenerateMapFile();
134 template <
class TInputImage>
138 if (itksys::SystemTools::GetFilenameLastExtension(m_FileName) !=
".map")
140 itkExceptionMacro(<< itksys::SystemTools::GetFilenameLastExtension(m_FileName) <<
" is a wrong Extension FileName : Expected .map");
144 this->InitializeVectorData();
151 template <
class TInputImage>
155 m_VectorDataIndexTile = VectorDataType::New();
159 m_Folder = DataNodeType::New();
165 document->SetNodeId(
"DOCUMENT");
166 m_Folder->SetNodeId(
"FOLDER");
168 m_VectorDataIndexTile->GetDataTree()->Add(document, root);
169 m_VectorDataIndexTile->GetDataTree()->Add(m_Folder, document);
175 template <
class TInputImage>
178 unsigned int numberOfChannel = m_VectorImage->GetNumberOfComponentsPerPixel();
181 typename InputImageType::PixelType inMin(numberOfChannel), inMax(numberOfChannel), outMin(numberOfChannel), outMax(numberOfChannel);
187 m_VectorImage->UpdateOutputInformation();
191 size = m_VectorImage->GetLargestPossibleRegion().GetSize();
193 unsigned int sizeX = size[0];
194 unsigned int sizeY = size[1];
197 unsigned int maxDepth =
static_cast<unsigned int>(std::max(std::ceil(std::log(
static_cast<float>(sizeX) /
static_cast<float>(m_TileSize)) / std::log(2.0)),
198 std::ceil(std::log(
static_cast<float>(sizeY) /
static_cast<float>(m_TileSize)) / std::log(2.0))));
204 for (
unsigned int depth = 0; depth <= maxDepth; depth++)
207 m_CurrentDepth = depth;
211 std::ostringstream tempIndexShapeName;
212 tempIndexShapeName << m_ShapeIndexPath <<
"/";
213 tempIndexShapeName << itksys::SystemTools::GetFilenameWithoutExtension(m_FileName) <<
"_" << m_CurrentDepth;
214 tempIndexShapeName <<
"_index.shp";
215 m_IndexShapeFileName = tempIndexShapeName.str();
218 int sampleRatioValue = 1 << (maxDepth - depth);
220 if (sampleRatioValue > 1)
222 m_StreamingShrinkImageFilter = StreamingShrinkImageFilterType::New();
224 m_StreamingShrinkImageFilter->SetShrinkFactor(sampleRatioValue);
225 m_StreamingShrinkImageFilter->SetInput(m_VectorImage);
226 m_StreamingShrinkImageFilter->GetStreamer()->SetAutomaticStrippedStreaming(0);
227 m_StreamingShrinkImageFilter->Update();
229 m_VectorRescaleIntensityImageFilter = VectorRescaleIntensityImageFilterType::New();
230 m_VectorRescaleIntensityImageFilter->SetInput(m_StreamingShrinkImageFilter->GetOutput());
231 m_VectorRescaleIntensityImageFilter->SetOutputMinimum(outMin);
232 m_VectorRescaleIntensityImageFilter->SetOutputMaximum(outMax);
236 m_VectorRescaleIntensityImageFilter->Update();
237 inMin = m_VectorRescaleIntensityImageFilter->GetInputMinimum();
238 inMax = m_VectorRescaleIntensityImageFilter->GetInputMaximum();
242 m_VectorRescaleIntensityImageFilter->SetInputMinimum(inMin);
243 m_VectorRescaleIntensityImageFilter->SetInputMaximum(inMax);
244 m_VectorRescaleIntensityImageFilter->SetAutomaticInputMinMaxComputation(
false);
248 m_ResampleVectorImage = m_VectorRescaleIntensityImageFilter->GetOutput();
252 m_VectorRescaleIntensityImageFilter = VectorRescaleIntensityImageFilterType::New();
253 m_VectorRescaleIntensityImageFilter->SetInput(m_VectorImage);
254 m_VectorRescaleIntensityImageFilter->SetOutputMinimum(outMin);
255 m_VectorRescaleIntensityImageFilter->SetOutputMaximum(outMax);
257 m_VectorRescaleIntensityImageFilter->SetInputMinimum(inMin);
258 m_VectorRescaleIntensityImageFilter->SetInputMaximum(inMax);
259 m_VectorRescaleIntensityImageFilter->SetAutomaticInputMinMaxComputation(
false);
261 m_ResampleVectorImage = m_VectorRescaleIntensityImageFilter->GetOutput();
264 m_ResampleVectorImage->UpdateOutputInformation();
267 size = m_ResampleVectorImage->GetLargestPossibleRegion().GetSize();
277 std::ostringstream path;
278 path << m_ShapeIndexPath <<
"/tiles";
280 if (!itksys::SystemTools::MakeDirectory(path.str()))
282 itkExceptionMacro(<<
"Error while creating cache directory" << path.str());
286 for (
unsigned int tx = 0; tx < sizeX; tx += m_TileSize)
288 for (
unsigned int ty = 0; ty < sizeY; ty += m_TileSize)
290 if ((tx + m_TileSize) >= sizeX)
292 extractIndex[0] = tx;
293 extractSize[0] = sizeX - tx;
297 extractIndex[0] = tx;
298 extractSize[0] = m_TileSize;
301 if ((ty + m_TileSize) >= sizeY)
303 extractIndex[1] = ty;
304 extractSize[1] = sizeY - ty;
308 extractIndex[1] = ty;
309 extractSize[1] = m_TileSize;
313 std::ostringstream ossFileName;
314 ossFileName << path.str() <<
"/";
315 ossFileName <<
"tile_" << m_CurrentDepth <<
"_";
316 ossFileName << x <<
"_" << y <<
".tif";
319 m_VectorImageExtractROIFilter = VectorImageExtractROIFilterType::New();
322 m_VectorImageExtractROIFilter->SetStartX(extractIndex[0]);
323 m_VectorImageExtractROIFilter->SetStartY(extractIndex[1]);
324 m_VectorImageExtractROIFilter->SetSizeX(extractSize[0]);
325 m_VectorImageExtractROIFilter->SetSizeY(extractSize[1]);
328 m_VectorImageExtractROIFilter->SetChannel(1);
329 m_VectorImageExtractROIFilter->SetChannel(2);
330 m_VectorImageExtractROIFilter->SetChannel(3);
333 m_VectorImageExtractROIFilter->SetInput(m_ResampleVectorImage);
336 m_VectorWriter = VectorWriterType::New();
337 m_VectorWriter->SetFileName(ossFileName.str());
338 m_VectorWriter->SetInput(m_VectorImageExtractROIFilter->GetOutput());
339 m_VectorWriter->Update();
348 m_Transform = TransformType::New();
349 m_Transform->SetInputProjectionRef(m_GenericRSResampler->GetOutputProjectionRef());
351 m_Transform->InstantiateTransform();
355 sizeTile = extractSize;
359 itk::ContinuousIndex<double, 2> indexTile(extractIndex);
360 indexTile[0] += -0.5;
361 indexTile[1] += -0.5;
362 m_ResampleVectorImage->TransformContinuousIndexToPhysicalPoint(indexTile, inputPoint);
363 OutputPointType upperLeftCorner = m_Transform->TransformPoint(inputPoint);
368 indexTile[1] +=
static_cast<double>(sizeTile[1]);
369 m_ResampleVectorImage->TransformContinuousIndexToPhysicalPoint(indexTile, inputPoint);
370 OutputPointType lowerLeftCorner = m_Transform->TransformPoint(inputPoint);
374 indexTile[0] +=
static_cast<double>(sizeTile[0]);
375 m_ResampleVectorImage->TransformContinuousIndexToPhysicalPoint(indexTile, inputPoint);
376 OutputPointType lowerRightCorner = m_Transform->TransformPoint(inputPoint);
380 indexTile[1] -=
static_cast<double>(sizeTile[1]);
381 m_ResampleVectorImage->TransformContinuousIndexToPhysicalPoint(indexTile, inputPoint);
382 OutputPointType upperRightCorner = m_Transform->TransformPoint(inputPoint);
386 this->AddBBoxToIndexTile(lowerLeftCorner, lowerRightCorner, upperRightCorner, upperLeftCorner, x, y);
400 writer->SetFileName(m_IndexShapeFileName);
401 writer->SetInput(m_VectorDataIndexTile);
404 this->InitializeVectorData();
408 m_File <<
"END" << std::endl;
416 template <
class TInputImage>
423 pLL[0] = lowerLeftCorner[0];
424 pLL[1] = lowerLeftCorner[1];
426 pLR[0] = lowerRightCorner[0];
427 pLR[1] = lowerRightCorner[1];
429 pUR[0] = upperRightCorner[0];
430 pUR[1] = upperRightCorner[1];
432 pUL[0] = upperLeftCorner[0];
433 pUL[1] = upperLeftCorner[1];
437 poly->AddVertex(pLL);
438 poly->AddVertex(pLR);
439 poly->AddVertex(pUR);
440 poly->AddVertex(pUL);
443 m_Polygon = DataNodeType::New();
444 m_Polygon->SetNodeId(
"FEATURE_POLYGON");
446 m_Polygon->SetPolygonExteriorRing(poly);
448 std::ostringstream oss;
449 oss <<
"tiles/tile_";
450 oss << m_CurrentDepth <<
"_" << x <<
"_" << y <<
".tif";
454 m_Polygon->SetFieldAsString(
"LOCATION", oss.str());
457 m_VectorDataIndexTile->GetDataTree()->Add(m_Polygon, m_Folder);
463 template <
class TInputImage>
468 std::ostringstream path;
469 path << itksys::SystemTools::GetFilenamePath(m_FileName);
472 if (!itksys::SystemTools::MakeDirectory(path.str()))
474 itkExceptionMacro(<<
"Error while creating cache directory" << path.str());
478 m_File.open(m_FileName);
479 m_File << std::fixed << std::setprecision(6);
482 std::ostringstream tempIndexShapeName;
483 tempIndexShapeName << itksys::SystemTools::GetFilenameWithoutExtension(m_FileName);
485 m_File <<
"MAP" << std::endl;
486 m_File <<
"\tNAME " << tempIndexShapeName.str() << std::endl;
487 m_File <<
"\t# Map image size" << std::endl;
488 m_File <<
"\tSIZE " << m_TileSize <<
" " << m_TileSize << std::endl;
489 m_File <<
"\tUNITS dd" << std::endl;
490 m_File <<
"\tSHAPEPATH '" << m_ShapeIndexPath <<
"'" << std::endl;
491 m_File <<
"\tEXTENT -180 -90 180 90" << std::endl;
494 m_File <<
"\tPROJECTION" << std::endl;
495 m_File <<
"\t \"init=epsg:" << m_SRID <<
"\"" << std::endl;
496 m_File <<
"\tEND" << std::endl;
498 m_File <<
"\t# Background color for the map canvas -- change as desired" << std::endl;
499 m_File <<
"\tIMAGECOLOR 192 192 192" << std::endl;
500 m_File <<
"\tIMAGEQUALITY 95" << std::endl;
501 m_File <<
"\tIMAGETYPE PNG" << std::endl;
502 m_File <<
"\tOUTPUTFORMAT" << std::endl;
503 m_File <<
"\t\tNAME PNG" << std::endl;
504 m_File <<
"\t\tDRIVER 'GD/PNG'" << std::endl;
505 m_File <<
"\t\tMIMETYPE 'image/png'" << std::endl;
506 m_File <<
"\t\tIMAGEMODE RGB" << std::endl;
507 m_File <<
"\t\tFORMATOPTION INTERLACE=OFF" << std::endl;
508 m_File <<
"\t\tEXTENSION 'png'" << std::endl;
509 m_File <<
"\tEND" << std::endl;
512 m_File <<
"\t# Web interface definition. Only the template parameter" << std::endl;
513 m_File <<
"\t# is required to display a map. See MapServer documentation" << std::endl;
514 m_File <<
"\tWEB" << std::endl;
515 m_File <<
"\t\t# Set IMAGEPATH to the path where MapServer should" << std::endl;
516 m_File <<
"\t\t# write its output." << std::endl;
519 m_File <<
"\t\t# Set IMAGEURL to the url that points to IMAGEPATH" << std::endl;
520 m_File <<
"\t\t# as defined in your web server configuration" << std::endl;
521 m_File <<
"\t\t#IMAGEURL '/ms_tmp/'" << std::endl;
523 m_File <<
"\t\t# WMS server settings" << std::endl;
524 m_File <<
"\t\t# NOTE : the user must change the path to the mapserver executable in the " << std::endl;
525 m_File <<
"\t\t# wms_onlineresource field" << std::endl;
526 m_File <<
"\t\tMETADATA" << std::endl;
527 m_File <<
"\t\t 'wms_title' 'Level0'" << std::endl;
528 m_File <<
"\t\t \'wms_onlineresource\' \'" << m_CGIPath <<
"?map=" << m_FileName <<
"&\'" << std::endl;
529 m_File <<
"\t\t \'wms_srs\' \'EPSG:" << m_SRID <<
" EPSG:900913\'" << std::endl;
530 m_File <<
"\t\tEND" << std::endl;
531 m_File <<
"\tEND" << std::endl;
535 template <
class TInputImage>
538 m_File <<
"\tLAYER" << std::endl;
539 m_File <<
"\t\tNAME '" << itksys::SystemTools::GetFilenameWithoutExtension(m_IndexShapeFileName) <<
"'" << std::endl;
540 m_File <<
"\t\t\tOFFSITE 0 0 0" << std::endl;
541 m_File <<
"\t\t\tTYPE RASTER" << std::endl;
542 m_File <<
"\t\t\tTILEITEM 'LOCATION'" << std::endl;
543 m_File <<
"\t\t\tTILEINDEX \'" << itksys::SystemTools::GetFilenameName(m_IndexShapeFileName) <<
"\'" << std::endl;
548 m_File <<
"\t\t\tPROCESSING \"RESAMPLE=AVERAGE\"" << std::endl;
549 m_File <<
"\t\t\tSTATUS ON" << std::endl;
550 m_File <<
"\t\t\tTRANSPARENCY 100" << std::endl;
551 m_File <<
"\t\t\tPROJECTION" << std::endl;
552 m_File <<
"\t\t\t \"init=epsg:" << m_SRID <<
"\"" << std::endl;
553 m_File <<
"\t\t\tEND" << std::endl;
554 m_File <<
"\t\t#MINSCALE 250000" << std::endl;
557 m_File <<
"\tEND" << std::endl;
560 template <
class TInputImage>
564 Superclass::PrintSelf(os, indent);