diff --git a/Applications/DataExplorer/DataView/GeoTreeView.cpp b/Applications/DataExplorer/DataView/GeoTreeView.cpp
index 7fe5c9967ac7eb6ba56acd0e2564d65f0c94c121..d2f6b4e6daed4ad0f9f2ecdf3207ab0c49e7c474 100644
--- a/Applications/DataExplorer/DataView/GeoTreeView.cpp
+++ b/Applications/DataExplorer/DataView/GeoTreeView.cpp
@@ -125,6 +125,13 @@ void GeoTreeView::contextMenuEvent( QContextMenuEvent* event )
     // The current index is a list of points/polylines/surfaces
     if (list != nullptr)
     {
+        QAction* convertToStationAction(nullptr);
+        if (list->getType() == GeoLib::GEOTYPE::POINT)
+        {
+            convertToStationAction = menu.addAction("Convert to Stations");
+            connect(convertToStationAction, SIGNAL(triggered()),
+                    this, SLOT(convertPointsToStations()));
+        }
         QAction* connectPlyAction(nullptr);
         if (list->getType() == GeoLib::GEOTYPE::POLYLINE)
         {
@@ -183,6 +190,14 @@ void GeoTreeView::contextMenuEvent( QContextMenuEvent* event )
     menu.exec(event->globalPos());
 }
 
+void GeoTreeView::convertPointsToStations()
+{
+    TreeItem const*const item = static_cast<GeoTreeModel*>(model())
+                         ->getItem(this->selectionModel()->currentIndex())
+                         ->parentItem();
+    emit requestPointToStationConversion(item->data(0).toString().toStdString());
+}
+
 void GeoTreeView::connectPolylines()
 {
     TreeItem* item = static_cast<GeoTreeModel*>(model())->getItem(
diff --git a/Applications/DataExplorer/DataView/GeoTreeView.h b/Applications/DataExplorer/DataView/GeoTreeView.h
index 03e601f484a0c03f263b42a1b0618dcfcdaa10d5..5b2d2df63f82e9664db26d1a2d3b9722e43f0dce 100644
--- a/Applications/DataExplorer/DataView/GeoTreeView.h
+++ b/Applications/DataExplorer/DataView/GeoTreeView.h
@@ -58,6 +58,7 @@ private slots:
     void on_Clicked(QModelIndex idx);
     /// Calls a LineEditDialog.
     void connectPolylines();
+    void convertPointsToStations();
     void mapGeometry();
     /// Calls a SetNameDialog.
     void setNameForElement();
@@ -84,5 +85,6 @@ signals:
     void requestCondSetupDialog(const std::string&, const GeoLib::GEOTYPE, const std::size_t, bool on_points);
     void requestLineEditDialog(const std::string&);
     void requestNameChangeDialog(const std::string&, const GeoLib::GEOTYPE, const std::size_t);
+    void requestPointToStationConversion(std::string const&);
     //void saveFEMConditionsRequested(QString, QString);
 };
diff --git a/Applications/DataExplorer/mainwindow.cpp b/Applications/DataExplorer/mainwindow.cpp
index 000116abbd4896a27fa936d60b6fae7d671d6742..d3c3ff9df5474a585c9ce58cf29d7c44835ee0ca 100644
--- a/Applications/DataExplorer/mainwindow.cpp
+++ b/Applications/DataExplorer/mainwindow.cpp
@@ -139,6 +139,8 @@ MainWindow::MainWindow(QWidget* parent /* = 0*/)
             this, SLOT(mapGeometry(const std::string&)));
     connect(geoTabWidget->treeView, SIGNAL(saveToFileRequested(QString, QString)),
             this, SLOT(writeGeometryToFile(QString, QString))); // save geometry to file
+    connect(geoTabWidget->treeView, SIGNAL(requestPointToStationConversion(std::string const&)), this,
+            SLOT(convertPointsToStations( std::string const&)));
     connect(geoTabWidget->treeView, SIGNAL(requestLineEditDialog(const std::string &)),
             this, SLOT(showLineEditDialog(const std::string &))); // open line edit dialog
     connect(geoTabWidget->treeView, SIGNAL(requestNameChangeDialog(const std::string&, const GeoLib::GEOTYPE, std::size_t)),
@@ -1097,6 +1099,12 @@ void MainWindow::showMeshAnalysisDialog()
     dlg->exec();
 }
 
+void MainWindow::convertPointsToStations(std::string const& geo_name)
+{
+    std::string const stn_name = geo_name + "Stations";
+    _project.getGEOObjects().geoPointsToStation(geo_name, stn_name);
+}
+
 void MainWindow::showLineEditDialog(const std::string &geoName)
 {
     LineEditDialog lineEdit(
diff --git a/Applications/DataExplorer/mainwindow.h b/Applications/DataExplorer/mainwindow.h
index 5765f0c6416df39c907ec79bdace24d7b06e9916..8baee849e3b12f01621b4df88c8f8cdd911e2459 100644
--- a/Applications/DataExplorer/mainwindow.h
+++ b/Applications/DataExplorer/mainwindow.h
@@ -76,6 +76,7 @@ protected slots:
     void loadPetrelFiles();
     void mapGeometry(const std::string &geo_name);
     void convertMeshToGeometry(const MeshLib::Mesh* mesh);
+    void convertPointsToStations(std::string const& geo_name);
     void openRecentFile();
     void about();
     void showAddPipelineFilterItemDialog(QModelIndex parentIndex);
diff --git a/GeoLib/GEOObjects.cpp b/GeoLib/GEOObjects.cpp
index ee1d9baa8ef4d55dbdb5c981e59137017c204c50..fb6b4856160db7eb9a8a0501d12888cab89c61bf 100644
--- a/GeoLib/GEOObjects.cpp
+++ b/GeoLib/GEOObjects.cpp
@@ -554,9 +554,83 @@ void GEOObjects::renameGeometry(std::string const& old_name,
     }
 }
 
-const GeoLib::GeoObject* GEOObjects::getGeoObject(const std::string &geo_name,
-                                                            GeoLib::GEOTYPE type,
-                                                            const std::string &geo_obj_name) const
+void GEOObjects::markPointsAsUsed(std::string const& geo_name,
+                                  std::vector<bool>& flags)
+{
+    GeoLib::PolylineVec const* const ply_obj(getPolylineVecObj(geo_name));
+    if (ply_obj)
+    {
+        std::vector<GeoLib::Polyline*> const& lines(*ply_obj->getVector());
+        for (auto line : lines)
+        {
+            std::size_t const n_pnts(line->getNumberOfPoints());
+            for (std::size_t i = 0; i < n_pnts; ++i)
+                flags[line->getPointID(i)] = false;
+        }
+    }
+
+    GeoLib::SurfaceVec const* const sfc_obj(getSurfaceVecObj(geo_name));
+    if (sfc_obj)
+    {
+        std::vector<GeoLib::Surface*> const& surfaces = *sfc_obj->getVector();
+        for (auto sfc : surfaces)
+        {
+            std::size_t const n_tri(sfc->getNumberOfTriangles());
+            for (std::size_t i = 0; i < n_tri; ++i)
+            {
+                GeoLib::Triangle const& t = *(*sfc)[i];
+                flags[t[0]] = false;
+                flags[t[1]] = false;
+                flags[t[2]] = false;
+            }
+        }
+    }
+}
+
+void GEOObjects::geoPointsToStation(std::string const& geo_name,
+                                    std::string const& stn_name,
+                                    bool only_unused_pnts)
+{
+    GeoLib::PointVec const* const pnt_obj(getPointVecObj(geo_name));
+    if (pnt_obj == nullptr)
+    {
+        ERR("Point vector %s not found.", geo_name.c_str());
+        return;
+    }
+    std::vector<GeoLib::Point*> const& pnts = *pnt_obj->getVector();
+    if (pnts.empty())
+    {
+        ERR("Point vector %s is empty.", geo_name.c_str());
+        return;
+    }
+    std::size_t const n_pnts(pnts.size());
+    std::vector<bool> flags(n_pnts, true);
+    if (only_unused_pnts)
+        markPointsAsUsed(geo_name, flags);
+
+    std::unique_ptr<std::vector<GeoLib::Point*>> stations(
+        new std::vector<GeoLib::Point*>);
+    for (std::size_t i = 0; i < n_pnts; ++i)
+    {
+        if (!flags[i])
+            continue;
+        std::string name = pnt_obj->getItemNameByID(i);
+        if (name.empty())
+            name = "Station " + std::to_string(i);
+        stations->push_back(new GeoLib::Station((*pnts[i])[0], (*pnts[i])[1],
+                                                (*pnts[i])[2], name));
+    }
+    std::string vec_name = geo_name + " stations";
+    if (!stations->empty())
+        addStationVec(std::move(stations), vec_name);
+    else
+        WARN("No points found to convert.");
+}
+
+const GeoLib::GeoObject* GEOObjects::getGeoObject(
+    const std::string& geo_name,
+    GeoLib::GEOTYPE type,
+    const std::string& geo_obj_name) const
 {
     GeoLib::GeoObject *geo_obj(nullptr);
     switch (type) {
diff --git a/GeoLib/GEOObjects.h b/GeoLib/GEOObjects.h
index 15f0ef42bafb7330707e5e29565c74bce786c659..8365b7e563906a785f722542030d1db31221cba7 100644
--- a/GeoLib/GEOObjects.h
+++ b/GeoLib/GEOObjects.h
@@ -249,6 +249,15 @@ public:
     void renameGeometry(std::string const& old_name,
                         std::string const& new_name);
 
+    /// Constucts a station-vector based on the points of a given geometry.
+    // @param geo_name name of the geometry
+    // @param stn_name name of the new station vector
+    // @param only_usused_pnts if true only points not in a line or surface are
+    // transferred, otherwise all points
+    void geoPointsToStation(std::string const& geo_name,
+                            std::string const& stn_name,
+                            bool only_unused_pnts = true);
+
     /// Returns the geo object for a geometric item of the given name and type for the associated geometry.
     const GeoLib::GeoObject* getGeoObject(const std::string &geo_name,
                                           GeoLib::GEOTYPE type,
@@ -367,5 +376,8 @@ private:
      */
     void mergeSurfaces(std::vector<std::string> const & geo_names,
             std::string & merged_geo_name, std::vector<std::size_t> const& pnt_offsets);
+
+    void markPointsAsUsed(std::string const& geo_name,
+                          std::vector<bool>& flags);
 };
 } // end namespace