diff --git a/IGNMap/Builds/LinuxMakefile/Makefile b/IGNMap/Builds/LinuxMakefile/Makefile
index 73209cc..1be589c 100644
--- a/IGNMap/Builds/LinuxMakefile/Makefile
+++ b/IGNMap/Builds/LinuxMakefile/Makefile
@@ -250,6 +250,7 @@ OBJECTS_APP := \
$(JUCE_OBJDIR)/DtmLayersViewer_98c8b452.o \
$(JUCE_OBJDIR)/DtmShader_bfa70483.o \
$(JUCE_OBJDIR)/ExportImageDlg_2dc44e1.o \
+ $(JUCE_OBJDIR)/ExportLasDlg_f653953e.o \
$(JUCE_OBJDIR)/GeoBase_343e9923.o \
$(JUCE_OBJDIR)/ImageLayersViewer_843f60d0.o \
$(JUCE_OBJDIR)/ImageOptionsViewer_66bba7be.o \
@@ -1251,6 +1252,11 @@ $(JUCE_OBJDIR)/ExportImageDlg_2dc44e1.o: ../../Source/ExportImageDlg.cpp
@echo "Compiling ExportImageDlg.cpp"
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
+$(JUCE_OBJDIR)/ExportLasDlg_f653953e.o: ../../Source/ExportLasDlg.cpp
+ -$(V_AT)mkdir -p $(@D)
+ @echo "Compiling ExportLasDlg.cpp"
+ $(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
+
$(JUCE_OBJDIR)/GeoBase_343e9923.o: ../../Source/GeoBase.cpp
-$(V_AT)mkdir -p $(@D)
@echo "Compiling GeoBase.cpp"
diff --git a/IGNMap/Builds/LinuxMakefile/build/IGNMap b/IGNMap/Builds/LinuxMakefile/build/IGNMap
index ae54eba..3ed79c3 100644
Binary files a/IGNMap/Builds/LinuxMakefile/build/IGNMap and b/IGNMap/Builds/LinuxMakefile/build/IGNMap differ
diff --git a/IGNMap/Builds/VisualStudio2022/IGNMap_App.vcxproj b/IGNMap/Builds/VisualStudio2022/IGNMap_App.vcxproj
index cd0fecd..410e4d5 100644
--- a/IGNMap/Builds/VisualStudio2022/IGNMap_App.vcxproj
+++ b/IGNMap/Builds/VisualStudio2022/IGNMap_App.vcxproj
@@ -329,6 +329,7 @@ COPY ..\..\Images\*.* .\x64\Release\App\Images
+
@@ -1901,6 +1902,7 @@ COPY ..\..\Images\*.* .\x64\Release\App\Images
+
diff --git a/IGNMap/Builds/VisualStudio2022/IGNMap_App.vcxproj.filters b/IGNMap/Builds/VisualStudio2022/IGNMap_App.vcxproj.filters
index 4b62cd9..109d6cd 100644
--- a/IGNMap/Builds/VisualStudio2022/IGNMap_App.vcxproj.filters
+++ b/IGNMap/Builds/VisualStudio2022/IGNMap_App.vcxproj.filters
@@ -847,6 +847,9 @@
IGNMap\Source
+
+ IGNMap\Source
+
IGNMap\Source
@@ -2952,6 +2955,9 @@
IGNMap\Source
+
+ IGNMap\Source
+
IGNMap\Source
diff --git a/IGNMap/Builds/VisualStudio2022/icon.ico b/IGNMap/Builds/VisualStudio2022/icon.ico
new file mode 100644
index 0000000..3b9d052
Binary files /dev/null and b/IGNMap/Builds/VisualStudio2022/icon.ico differ
diff --git a/IGNMap/Builds/VisualStudio2022/x64/Release/App/IGNMap.exe b/IGNMap/Builds/VisualStudio2022/x64/Release/App/IGNMap.exe
index 4e84728..e3f9d5d 100644
Binary files a/IGNMap/Builds/VisualStudio2022/x64/Release/App/IGNMap.exe and b/IGNMap/Builds/VisualStudio2022/x64/Release/App/IGNMap.exe differ
diff --git a/IGNMap/IGNMap.jucer b/IGNMap/IGNMap.jucer
index c635d6e..8bcbbf2 100644
--- a/IGNMap/IGNMap.jucer
+++ b/IGNMap/IGNMap.jucer
@@ -434,6 +434,9 @@
file="Source/ExportImageDlg.cpp"/>
+
+
file_source_ID = 0;
+ m_Header->global_encoding = (1 << 0) | (1 << 4); // see LAS specification for details
+ m_Header->version_major = 1;
+ m_Header->version_minor = 4;
+ strncpy(m_Header->system_identifier, "Export LAS IGNMap", 32);
+ strncpy(m_Header->generating_software, "IGNMap v3", 32);
+ juce::Time time = juce::Time::getCurrentTime();
+ m_Header->file_creation_day = time.getDayOfYear();
+ m_Header->file_creation_year = time.getYear();
+ m_Header->header_size = 375;
+ m_Header->offset_to_point_data = 375;
+ m_Header->point_data_format = 6;
+ m_Header->point_data_record_length = 30;
+ m_Header->number_of_point_records = 0; // legacy 32-bit counters should be zero for new point types > 5
+ for (int i = 0; i < 5; i++) {
+ m_Header->number_of_points_by_return[i] = 0; // legacy 32-bit counters should be zero for new point types > 5
+ }
+ m_Header->extended_number_of_point_records = 0; // a-priori unknown number of points
+ for (int i = 0; i < 15; i++) {
+ m_Header->extended_number_of_points_by_return[i] = 0;
+ }
+ m_Header->max_x = 0.0; // a-priori unknown bounding box
+ m_Header->min_x = 0.0;
+ m_Header->max_y = 0.0;
+ m_Header->min_y = 0.0;
+ m_Header->max_z = 0.0;
+ m_Header->min_z = 0.0;
+
+ // Ajout de la projection
+ laszip_geokey_struct key_entries[5];
+
+ // projected coordinates
+ key_entries[0].key_id = 1024; // GTModelTypeGeoKey
+ key_entries[0].tiff_tag_location = 0;
+ key_entries[0].count = 1;
+ key_entries[0].value_offset = 1; // ModelTypeProjected
+
+ // projection
+ key_entries[1].key_id = 3072; // ProjectedCSTypeGeoKey
+ key_entries[1].tiff_tag_location = 0;
+ key_entries[1].count = 1;
+ key_entries[1].value_offset = 2154; // Lambert 93
+
+ // horizontal units
+ key_entries[2].key_id = 3076; // ProjLinearUnitsGeoKey
+ key_entries[2].tiff_tag_location = 0;
+ key_entries[2].count = 1;
+ key_entries[2].value_offset = 9001; // meters
+
+ // vertical units
+ key_entries[3].key_id = 4099; // VerticalUnitsGeoKey
+ key_entries[3].tiff_tag_location = 0;
+ key_entries[3].count = 1;
+ key_entries[3].value_offset = 9001; // meters
+
+ // vertical datum
+ key_entries[4].key_id = 4096; // VerticalCSTypeGeoKey
+ key_entries[4].tiff_tag_location = 0;
+ key_entries[4].count = 1;
+ key_entries[4].value_offset = 5720; // IGN69
+
+ // add the geokeys (create or replace the appropriate VLR)
+ if (laszip_set_geokeys(m_Writer, 5, key_entries))
+ return;
+ /*
+ if (laszip_add_vlr(m_Writer, "LASF_Projection", 2112, 0, "intentionally empty OGC WKT", 0))
+ return;
+ if (laszip_add_vlr(m_Writer, "funny", 12345, 0, "just a funny VLR", 0))
+ return;*/
+
+ laszip_BOOL compress = 0;
+ if (m_Compression) {
+ //laszip_BOOL request = 1;
+ //if (laszip_request_compatibility_mode(m_Writer, request))
+ // return;
+ compress = 1;
+ }
+
+ laszip_preserve_generating_software(m_Writer, 1);
+ if (laszip_open_writer(m_Writer, m_Filename.toStdString().c_str(), compress)) // Ouverture du Writer
+ return;
+
+ // Pointeur pour ecrire les points
+ if (laszip_get_point_pointer(m_Writer, &m_Point))
+ return;
+
+ // Ecriture des points
+ m_Count = 0;
+
+ for (uint32_t i = 0; i < m_GeoBase->NbClass(); i++) {
+ XGeoClass* C = m_GeoBase->Class(i);
+ if (C == nullptr)
+ continue;
+ if (!C->IsLAS())
+ continue;
+ if (!C->Visible())
+ continue;
+ if (!m_Frame.Intersect(C->Frame()))
+ continue;
+
+ for (uint32_t j = 0; j < C->NbVector(); j++) {
+ GeoLAS* las = (GeoLAS*)C->Vector(j);
+ XFrame F = las->Frame();
+ if (!m_Frame.Intersect(F))
+ continue;
+ ExportLas(las);
+ if (threadShouldExit())
+ return;
+ }
+ }
+
+ // Fermeture du Writer
+ if (laszip_get_point_count(m_Writer, &m_Count))
+ return;
+
+ if (laszip_close_writer(m_Writer))
+ return;
+
+ if (laszip_destroy(m_Writer))
+ return;
+
+
+}
+
+//==============================================================================
+// Export d'un fichier LAS
+//==============================================================================
+void LasExportThread::ExportLas(GeoLAS* las)
+{
+ laszip_I64 npoints = las->NbLasPoints();
+ laszip_POINTER reader = las->GetReader();
+ laszip_header* header = las->GetHeader();
+ laszip_point* point = las->GetPoint();
+
+ laszip_seek_point(reader, 0);
+ double Xmin = (m_Frame.Xmin - header->x_offset) / header->x_scale_factor;
+ double Xmax = (m_Frame.Xmax - header->x_offset) / header->x_scale_factor;
+ double Ymin = (m_Frame.Ymin - header->y_offset) / header->y_scale_factor;
+ double Ymax = (m_Frame.Ymax - header->y_offset) / header->y_scale_factor;
+ double Zmin = (LasShader::Zmin() - header->z_offset) / header->z_scale_factor;
+ double Zmax = (LasShader::Zmax() - header->z_offset) / header->z_scale_factor;
+
+ uint8_t classification;
+ bool classif_newtype = true;
+ if (header->version_minor < 4) classif_newtype = false;
+ LasShader shader;
+ laszip_F64 coordinates[3];
+ for (laszip_I64 i = 0; i < npoints; i++) {
+ laszip_read_point(reader);
+ if (classif_newtype)
+ classification = point->extended_classification;
+ else
+ classification = point->classification;
+ if (!shader.ClassificationVisibility(classification)) continue;
+ if (point->X <= Xmin) continue;
+ if (point->X >= Xmax) continue;
+ if (point->Y <= Ymin) continue;
+ if (point->Y >= Ymax) continue;
+ if (point->Z < Zmin) continue;
+ if (point->Z > Zmax) continue;
+
+ coordinates[0] = point->X * header->x_scale_factor + header->x_offset;
+ coordinates[1] = point->Y * header->y_scale_factor + header->y_offset;
+ coordinates[2] = point->Z * header->z_scale_factor + header->z_offset;
+ if (laszip_set_coordinates(m_Writer, coordinates))
+ return;
+
+ m_Point->intensity = point->intensity;
+ m_Point->extended_return_number = point->extended_return_number;
+ m_Point->extended_number_of_returns = point->extended_number_of_returns;
+ m_Point->classification = point->classification; // it must be set because it "fits" in 5 bits
+ m_Point->extended_classification = point->extended_classification;
+ m_Point->extended_scan_angle = point->extended_scan_angle;
+ m_Point->extended_scanner_channel = point->extended_scanner_channel;
+ m_Point->extended_classification_flags = point->extended_classification_flags; // overflag flag is set
+ m_Point->gps_time = point->gps_time;
+
+ if (laszip_write_point(m_Writer))
+ return;
+ if (laszip_update_inventory(m_Writer))
+ return;
+ m_Count++;
+ }
+}
+
+
+//==============================================================================
+// Constructeur
+//==============================================================================
+ExportLasDlg::ExportLasDlg(XGeoBase* base, double xmin, double ymin, double xmax,
+ double ymax) : m_ExportThread("ExportThread")
+{
+ m_Base = base;
+
+ addAndMakeVisible(m_lblXmin);
+ m_lblXmin.setBounds(10, 50, 50, 24);
+ m_lblXmin.setText(juce::translate("Xmin : "), juce::NotificationType::dontSendNotification);
+ addAndMakeVisible(m_edtXmin);
+ m_edtXmin.setBounds(60, 50, 100, 24);
+ m_edtXmin.setText(juce::String(xmin, 2));
+
+ addAndMakeVisible(m_lblXmax);
+ m_lblXmax.setBounds(350, 50, 50, 24);
+ m_lblXmax.setText(juce::translate(" : Xmax"), juce::NotificationType::dontSendNotification);
+ addAndMakeVisible(m_edtXmax);
+ m_edtXmax.setBounds(240, 50, 100, 24);
+ m_edtXmax.setText(juce::String(xmax, 2));
+
+ addAndMakeVisible(m_lblYmax);
+ m_lblYmax.setBounds(100, 10, 50, 24);
+ m_lblYmax.setText(juce::translate("Ymax : "), juce::NotificationType::dontSendNotification);
+ addAndMakeVisible(m_edtYmax);
+ m_edtYmax.setBounds(150, 10, 100, 24);
+ m_edtYmax.setText(juce::String(ymax, 2));
+
+ addAndMakeVisible(m_lblYmin);
+ m_lblYmin.setBounds(260, 90, 50, 24);
+ m_lblYmin.setText(juce::translate(" : Ymin"), juce::NotificationType::dontSendNotification);
+ addAndMakeVisible(m_edtYmin);
+ m_edtYmin.setBounds(150, 90, 100, 24);
+ m_edtYmin.setText(juce::String(ymin, 2));
+
+ addAndMakeVisible(m_btnLaz);
+ m_btnLaz.setButtonText(juce::translate("LAZ Compression"));
+ m_btnLaz.setBounds(140, 130, 120, 24);
+
+ addAndMakeVisible(m_btnExport);
+ m_btnExport.setButtonText(juce::translate("Export"));
+ m_btnExport.setBounds(160, 170, 80, 30);
+ m_btnExport.addListener(this);
+
+ m_progressBar = new juce::ProgressBar(m_dProgress);
+ addAndMakeVisible(m_progressBar);
+ m_progressBar->setBounds(100, 210, 200, 30);
+
+ addAndMakeVisible(m_edtFilename);
+ m_edtFilename.setBounds(10, 260, 380, 24);
+ m_edtFilename.setText("");
+ m_edtFilename.setReadOnly(true);
+}
+
+//==============================================================================
+// Destructeur
+//==============================================================================
+ExportLasDlg::~ExportLasDlg()
+{
+ delete m_progressBar;
+ stopTimer();
+ m_ExportThread.stopThread(5000);
+}
+
+//==============================================================================
+// Validation de l'export
+//==============================================================================
+void ExportLasDlg::buttonClicked(juce::Button* button)
+{
+ if (button != &m_btnExport)
+ return;
+ if (m_Base == nullptr)
+ return;
+ if (m_btnExport.getButtonText() == juce::translate("Cancel")) { // Annulation
+ stopTimer();
+ m_ExportThread.signalThreadShouldExit();
+ if (m_ExportThread.isThreadRunning())
+ m_ExportThread.stopThread(-1);
+ m_dProgress = 0.;
+ m_btnExport.setButtonText(juce::translate("Export"));
+ juce::File file(m_strFilename);
+ file.deleteFile();
+ return;
+ }
+
+ m_btnExport.setButtonText(juce::translate("Cancel"));
+
+ m_strFilename = m_edtFilename.getText();
+ m_Frame.Xmin = m_edtXmin.getText().getDoubleValue();
+ m_Frame.Xmax = m_edtXmax.getText().getDoubleValue();
+ m_Frame.Ymin = m_edtYmin.getText().getDoubleValue();
+ m_Frame.Ymax = m_edtYmax.getText().getDoubleValue();
+
+ m_dProgress = 0.;
+
+ // Creation du fichier LAS
+ juce::String ext = "*.las";
+ if (m_btnLaz.getToggleState())
+ ext = "*.laz";
+ m_strFilename = AppUtil::SaveFile("ExportLasFile", juce::translate("File to save"), ext);
+ if (m_strFilename.isEmpty())
+ return;
+
+ m_ExportThread.signalThreadShouldExit();
+ if (m_ExportThread.isThreadRunning()) {
+ if (!m_ExportThread.stopThread(-1))
+ return;
+ }
+
+ // Lancement du thread d'export
+ m_ExportThread.SetGeoBase(m_Base);
+ m_ExportThread.SetExportFrame(m_Frame);
+ m_ExportThread.SetFilename(m_strFilename);
+ if (m_btnLaz.getToggleState())
+ m_ExportThread.SetCompression(true);
+ m_ExportThread.startThread();
+
+ startTimerHz(10);
+}
+
+//==============================================================================
+// Callback du Timer
+//==============================================================================
+void ExportLasDlg::timerCallback()
+{
+ if (m_ExportThread.isThreadRunning()) {
+ m_dProgress++;
+ return;
+ }
+ m_dProgress = 1.;
+ stopTimer();
+ m_btnExport.setButtonText(juce::translate("Export"));
+ juce::File file(m_strFilename);
+ file.revealToUser();
+ juce::Component* parent = getParentComponent();
+ if (parent != nullptr)
+ delete parent;
+ return;
+}
\ No newline at end of file
diff --git a/IGNMap/Source/ExportLasDlg.h b/IGNMap/Source/ExportLasDlg.h
new file mode 100644
index 0000000..60feefe
--- /dev/null
+++ b/IGNMap/Source/ExportLasDlg.h
@@ -0,0 +1,69 @@
+//-----------------------------------------------------------------------------
+// ExportLasDlg.h
+// ==============
+//
+// Dialogue d'options pour exporter les fichiers LAS/LAZ
+//
+// Auteur : F.Becirspahic - IGN / DSI / SIMV
+// License : GNU AFFERO GENERAL PUBLIC LICENSE v3
+// Date de creation : 25/02/2024
+//-----------------------------------------------------------------------------
+
+#pragma once
+#include
+#include "GeoBase.h"
+
+class XGeoBase;
+
+//==============================================================================
+// Thread pour l'export
+//==============================================================================
+class LasExportThread : public juce::Thread {
+public:
+ LasExportThread(const juce::String& threadName, size_t threadStackSize = 0) : juce::Thread(threadName, threadStackSize) { m_GeoBase = nullptr; }
+ virtual ~LasExportThread() { ; }
+
+ void SetExportFrame(const XFrame& F) { m_Frame = F; }
+ void SetGeoBase(XGeoBase* base) { m_GeoBase = base; }
+ void SetFilename(juce::String name) { m_Filename = name; }
+ void SetCompression(bool compression) { m_Compression = compression; }
+
+ virtual void run() override;
+
+private:
+ XGeoBase* m_GeoBase;
+ XFrame m_Frame; // Cadre pour l'export
+ juce::String m_Filename;
+ bool m_Compression = false;
+ laszip_POINTER m_Writer = nullptr;
+ laszip_header* m_Header = nullptr;
+ laszip_point* m_Point = nullptr;
+ laszip_I64 m_Count = 0;
+
+ void ExportLas(GeoLAS* las);
+};
+
+//==============================================================================
+// Dialogue pour l'export
+//==============================================================================
+class ExportLasDlg : public juce::Component, public juce::Button::Listener, private juce::Timer {
+public:
+ ExportLasDlg(XGeoBase* base, double xmin = 0., double ymin = 0., double xmax = 0., double ymax = 0.);
+ virtual ~ExportLasDlg();
+ void buttonClicked(juce::Button*) override;
+
+private:
+ XGeoBase* m_Base;
+ juce::TextEditor m_edtXmin, m_edtYmin, m_edtXmax, m_edtYmax, m_edtFilename;
+ juce::Label m_lblXmin, m_lblYmin, m_lblXmax, m_lblYmax;
+ juce::TextButton m_btnExport;
+ juce::ToggleButton m_btnLaz;
+
+ LasExportThread m_ExportThread;
+ juce::String m_strFilename;
+ XFrame m_Frame;
+ double m_dProgress = 0.;
+ juce::ProgressBar* m_progressBar;
+
+ void timerCallback() override;
+};
\ No newline at end of file
diff --git a/IGNMap/Source/MainComponent.cpp b/IGNMap/Source/MainComponent.cpp
index 9a5e0f8..7b59a8d 100644
--- a/IGNMap/Source/MainComponent.cpp
+++ b/IGNMap/Source/MainComponent.cpp
@@ -14,6 +14,7 @@
#include "OsmLayer.h"
#include "WmtsLayer.h"
#include "ExportImageDlg.h"
+#include "ExportLasDlg.h"
#include "../../XToolGeod/XGeoPref.h"
#include "../../XToolImage/XTiffWriter.h"
@@ -195,6 +196,7 @@ juce::PopupMenu MainComponent::getMenuForIndex(int menuIndex, const juce::String
juce::PopupMenu ExportSubMenu;
ExportSubMenu.addCommandItem(&m_CommandManager, CommandIDs::menuExportImage);
+ ExportSubMenu.addCommandItem(&m_CommandManager, CommandIDs::menuExportLas);
menu.addSubMenu(juce::translate("Export"), ExportSubMenu);
menu.addCommandItem(&m_CommandManager, CommandIDs::menuQuit);
@@ -261,7 +263,7 @@ void MainComponent::getAllCommands(juce::Array& c)
CommandIDs::menuImportVectorFile, CommandIDs::menuImportVectorFolder,
CommandIDs::menuImportImageFile, CommandIDs::menuImportImageFolder, CommandIDs::menuImportDtmFile,
CommandIDs::menuImportDtmFolder, CommandIDs::menuImportLasFile, CommandIDs::menuImportLasFolder,
- CommandIDs::menuExportImage,
+ CommandIDs::menuExportImage, CommandIDs::menuExportLas,
CommandIDs::menuZoomTotal, CommandIDs::menuZoomLevel,
CommandIDs::menuTest, CommandIDs::menuShowSidePanel,
CommandIDs::menuShowVectorLayers, CommandIDs::menuShowImageLayers, CommandIDs::menuShowDtmLayers,
@@ -352,6 +354,9 @@ void MainComponent::getCommandInfo(juce::CommandID commandID, juce::ApplicationC
case CommandIDs::menuExportImage:
result.setInfo(juce::translate("Export image"), juce::translate("Export image"), "Menu", 0);
break;
+ case CommandIDs::menuExportLas:
+ result.setInfo(juce::translate("Export LAS"), juce::translate("Export LAS"), "Menu", 0);
+ break;
case CommandIDs::menuZoomTotal:
result.setInfo(juce::translate("Zoom total"), juce::translate("Zoom total"), "Menu", 0);
break;
@@ -501,6 +506,9 @@ bool MainComponent::perform(const InvocationInfo& info)
case CommandIDs::menuExportImage:
ExportImage();
break;
+ case CommandIDs::menuExportLas:
+ ExportLas();
+ break;
case CommandIDs::menuZoomTotal:
m_MapView.get()->ZoomWorld();
break;
@@ -747,8 +755,8 @@ void MainComponent::NewWindow()
//==============================================================================
void MainComponent::AboutIGNMap()
{
- juce::String version = "0.0.2";
- juce::String info = "18/02/2024";
+ juce::String version = "0.0.3";
+ juce::String info = "28/02/2024";
juce::String message = "IGNMap 3 Version : " + version + "\n" + info + "\n";
message += "JUCE Version : " + juce::String(JUCE_MAJOR_VERSION) + "."
+ juce::String(JUCE_MINOR_VERSION) + "." + juce::String(JUCE_BUILDNUMBER);
@@ -1011,7 +1019,7 @@ void MainComponent::ImportLasFolder()
juce::String folderName = AppUtil::OpenFolder("LasFolderPath");
if (folderName.isEmpty())
return;
- XGeoClass* C = ImportDataFolder(folderName, XGeoVector::LAS);
+ ImportDataFolder(folderName, XGeoVector::LAS);
m_LasViewer.get()->SetBase(&m_GeoBase);
m_MapView.get()->RenderMap(false, false, false, false, true, true);
}
@@ -1121,6 +1129,7 @@ bool MainComponent::AddWmtsServer(std::string server, std::string layer, std::st
//==============================================================================
bool MainComponent::ExportImage()
{
+ m_MapView.get()->StopThread();
XFrame F = m_MapView.get()->GetSelectionFrame();
double gsd = m_MapView.get()->GetGsd();
ExportImageDlg* dlg = new ExportImageDlg(&m_GeoBase, XRint(F.Xmin), XRint(F.Ymin), XRint(F.Xmax), XRint(F.Ymax), XRint(gsd));
@@ -1140,6 +1149,31 @@ bool MainComponent::ExportImage()
return true;
}
+//==============================================================================
+// Export sous forme d'un nuage de points LAS
+//==============================================================================
+bool MainComponent::ExportLas()
+{
+ m_MapView.get()->StopThread();
+ XFrame F = m_MapView.get()->GetSelectionFrame();
+ double gsd = m_MapView.get()->GetGsd();
+ ExportLasDlg* dlg = new ExportLasDlg(&m_GeoBase, XRint(F.Xmin), XRint(F.Ymin), XRint(F.Xmax), XRint(F.Ymax));
+ juce::DialogWindow::LaunchOptions options;
+ options.content.setOwned(dlg);
+
+ juce::Rectangle area(0, 0, 410, 300);
+
+ options.content->setSize(area.getWidth(), area.getHeight());
+ options.dialogTitle = juce::translate("Export LAS");
+ options.dialogBackgroundColour = juce::Colour(0xff0e345a);
+ options.escapeKeyTriggersCloseButton = true;
+ options.useNativeTitleBar = false;
+ options.resizable = false;
+
+ options.runModal();
+ return true;
+}
+
//==============================================================================
// Chargement d'un fichier de traduction
//==============================================================================
diff --git a/IGNMap/Source/MainComponent.h b/IGNMap/Source/MainComponent.h
index a39ee4c..6e8ba26 100644
--- a/IGNMap/Source/MainComponent.h
+++ b/IGNMap/Source/MainComponent.h
@@ -47,9 +47,9 @@ class MainComponent : public juce::Component,
menuNew = 1, menuQuit,
menuUndo,
menuTranslate, menuTest,
- menuImportVectorFolder, menuImportVectorFile, menuImportImageFolder, menuImportImageFile,
+ menuImportVectorFolder, menuImportVectorFile, menuImportImageFolder, menuImportImageFile,
menuImportDtmFolder, menuImportDtmFile, menuImportLasFile, menuImportLasFolder,
- menuExportImage,
+ menuExportImage, menuExportLas,
menuZoomTotal, menuZoomLevel,
menuScale1k, menuScale10k, menuScale25k, menuScale100k, menuScale250k,
menuShowSidePanel, menuShow3DViewer,
@@ -129,6 +129,7 @@ class MainComponent : public juce::Component,
bool ImportLasFile(juce::String lasfile = "");
bool ExportImage();
+ bool ExportLas();
bool AddOSMServer();
bool AddWmtsServer();
diff --git a/IGNMap/Source/MapThread.cpp b/IGNMap/Source/MapThread.cpp
index 3c3e9fd..d078064 100644
--- a/IGNMap/Source/MapThread.cpp
+++ b/IGNMap/Source/MapThread.cpp
@@ -815,7 +815,7 @@ bool MapThread::DrawLas(GeoLAS* las)
int W = (int)round(F.Width() / m_dGsd);
int H = (int)round(F.Height() / m_dGsd);
juce::Graphics g(m_Las);
- g.setColour(juce::Colours::mediumvioletred);
+ g.setColour(juce::Colours::lightpink);
g.fillRect((int)floor((F.Xmin - m_dX0) / m_dGsd), (int)floor((m_dY0 - F.Ymax) / m_dGsd), W, H);
m_nNumObjects++;
return true;
diff --git a/XToolAlgo/XLasFile.cpp b/XToolAlgo/XLasFile.cpp
index 483cec0..c654829 100644
--- a/XToolAlgo/XLasFile.cpp
+++ b/XToolAlgo/XLasFile.cpp
@@ -22,17 +22,18 @@ bool XLasFile::Open(std::string filename)
m_strFilename = "";
if (laszip_create(&m_Reader))
return false;
- laszip_BOOL compress;
+ laszip_BOOL compress = 0;
if (laszip_open_reader(m_Reader, filename.c_str(), &compress)) {
laszip_destroy(m_Reader);
+ m_Reader = nullptr;
return false;
}
if (laszip_get_header_pointer(m_Reader, &m_Header)) {
- laszip_destroy(m_Reader);
+ Close();
return false;
}
if (laszip_get_point_pointer(m_Reader, &m_Point)) {
- laszip_destroy(m_Reader);
+ Close();
return false;
}
@@ -50,6 +51,9 @@ bool XLasFile::Close()
laszip_close_reader(m_Reader);
laszip_destroy(m_Reader);
}
+ m_Reader = nullptr;
+ m_Header = nullptr;
+ m_Point = nullptr;
m_strFilename = "";
return true;
}