From 1e0426312155d264471c8e046ccbb13871783b82 Mon Sep 17 00:00:00 2001
From: sudo-panda <kundubaidya99@gmail.com>
Date: Sun, 5 Apr 2020 23:02:02 +0530
Subject: [PATCH 1/9] [ext][io] Add a basic implementation

- Currently only 3D points are supported
---
 .../geometry/extensions/io/plotly/plotter.hpp | 134 ++++++++++++++++++
 1 file changed, 134 insertions(+)
 create mode 100644 include/boost/geometry/extensions/io/plotly/plotter.hpp

diff --git a/include/boost/geometry/extensions/io/plotly/plotter.hpp b/include/boost/geometry/extensions/io/plotly/plotter.hpp
new file mode 100644
index 0000000000..3509308b44
--- /dev/null
+++ b/include/boost/geometry/extensions/io/plotly/plotter.hpp
@@ -0,0 +1,134 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2020 Baidyanath Kundu, Haldia, India.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_IO_PLOT_LY_PLOTTER_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_IO_PLOT_LY_PLOTTER_HPP
+
+#include <ostream>
+
+#include <boost/geometry/geometries/geometries.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DETAIL
+namespace detail { namespace json
+{
+
+template <typename Point>
+struct json_point_3
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+                Point const& p)
+    {
+        os << "{ \"mode\": \"markers\", \"type\": \"scatter3d\", "
+            << "\"x\": [\"" << geometry::get<0>(p) << "\"],"
+            << "\"y\": [\"" << geometry::get<1>(p) << "\"],"
+            << "\"z\": [\"" << geometry::get<2>(p) << "\"]}";
+    }
+};
+
+struct prefix_comma
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os)
+    {
+        os << ", ";
+    }
+};
+
+}} // namespace detail::json
+#endif // DOXYGEN_NO_DETAIL
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template 
+<
+    typename Geometry, 
+    typename Tag = typename tag<Geometry>::type, 
+    int Dimension = dimension<Geometry>::value
+>
+struct json_plot
+{
+    BOOST_MPL_ASSERT_MSG
+        (
+            false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+            , (Geometry)
+        );
+};
+
+template <typename Point>
+struct json_plot<Point, point_tag, 3> : detail::json::json_point_3<Point> 
+{};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+template <typename Geometry>
+inline void json_plot(std::ostream& stream, Geometry const& geometry)
+{
+    dispatch::json_plot<Geometry>::apply(stream, geometry);
+}
+
+
+class json_plotter : boost::noncopyable
+{
+    std::ostream& m_stream;
+    bool first;
+
+public:
+
+    json_plotter(std::ostream& stream)
+        : m_stream(stream)
+    {
+        m_stream << "{"
+                << std::endl
+                << "    data: [";
+        first = true;
+    }
+
+    virtual ~json_plotter()
+    {
+        m_stream << "], "
+                << std::endl
+                << "    layout: {\"scene\": {\"camera\": {\"up\": {\"x\": 0, \"y\": 0, \"z\": 1}, \"eye\": {\"x\": 0.2829440102575065, \"y\": 0.05402592432697305, \"z\": 2.14581543627592}, \"center\": {\"x\": 0, \"y\": 0, \"z\": 0}, \"projection\": {\"type\": \"perspective\"}}, \"aspectmode\": \"auto\", \"aspectratio\": {\"x\": 1, \"y\": 1, \"z\": 1}}, \"xaxis\": {\"range\": [-1, 6], \"autorange\": true}, \"yaxis\": {\"range\": [-1, 4], \"autorange\": true}, \"autosize\": true, \"template\": {\"data\": {\"bar\": [{\"type\": \"bar\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"table\": [{\"type\": \"table\", \"cells\": {\"fill\": {\"color\": \"#EBF0F8\"}, \"line\": {\"color\": \"white\"}}, \"header\": {\"fill\": {\"color\": \"#C8D4E3\"}, \"line\": {\"color\": \"white\"}}}], \"carpet\": [{\"type\": \"carpet\", \"aaxis\": {\"gridcolor\": \"#C8D4E3\", \"linecolor\": \"#C8D4E3\", \"endlinecolor\": \"#2a3f5f\", \"minorgridcolor\": \"#C8D4E3\", \"startlinecolor\": \"#2a3f5f\"}, \"baxis\": {\"gridcolor\": \"#C8D4E3\", \"linecolor\": \"#C8D4E3\", \"endlinecolor\": \"#2a3f5f\", \"minorgridcolor\": \"#C8D4E3\", \"startlinecolor\": \"#2a3f5f\"}}], \"mesh3d\": [{\"type\": \"mesh3d\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"contour\": [{\"type\": \"contour\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}, \"autocolorscale\": true}], \"heatmap\": [{\"type\": \"heatmap\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}, \"autocolorscale\": true}], \"scatter\": [{\"type\": \"scatter\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"surface\": [{\"type\": \"surface\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"heatmapgl\": [{\"type\": \"heatmapgl\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"histogram\": [{\"type\": \"histogram\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"parcoords\": [{\"line\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}, \"type\": \"parcoords\"}], \"scatter3d\": [{\"type\": \"scatter3d\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"scattergl\": [{\"type\": \"scattergl\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"choropleth\": [{\"type\": \"choropleth\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"scattergeo\": [{\"type\": \"scattergeo\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"histogram2d\": [{\"type\": \"histogram2d\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}, \"autocolorscale\": true}], \"scatterpolar\": [{\"type\": \"scatterpolar\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"contourcarpet\": [{\"type\": \"contourcarpet\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"scattercarpet\": [{\"type\": \"scattercarpet\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"scattermapbox\": [{\"type\": \"scattermapbox\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"scatterpolargl\": [{\"type\": \"scatterpolargl\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"scatterternary\": [{\"type\": \"scatterternary\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"histogram2dcontour\": [{\"type\": \"histogram2dcontour\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}, \"autocolorscale\": true}]}, \"layout\": {\"geo\": {\"bgcolor\": \"white\", \"showland\": true, \"lakecolor\": \"white\", \"landcolor\": \"white\", \"showlakes\": true, \"subunitcolor\": \"#C8D4E3\"}, \"font\": {\"color\": \"#2a3f5f\"}, \"polar\": {\"bgcolor\": \"white\", \"radialaxis\": {\"ticks\": \"\", \"gridcolor\": \"#EBF0F8\", \"linecolor\": \"#EBF0F8\"}, \"angularaxis\": {\"ticks\": \"\", \"gridcolor\": \"#EBF0F8\", \"linecolor\": \"#EBF0F8\"}}, \"scene\": {\"xaxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"gridwidth\": 2, \"linecolor\": \"#EBF0F8\", \"zerolinecolor\": \"#EBF0F8\", \"showbackground\": true, \"backgroundcolor\": \"white\"}, \"yaxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"gridwidth\": 2, \"linecolor\": \"#EBF0F8\", \"zerolinecolor\": \"#EBF0F8\", \"showbackground\": true, \"backgroundcolor\": \"white\"}, \"zaxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"gridwidth\": 2, \"linecolor\": \"#EBF0F8\", \"zerolinecolor\": \"#EBF0F8\", \"showbackground\": true, \"backgroundcolor\": \"white\"}}, \"title\": {\"x\": 0.05}, \"xaxis\": {\"ticks\": \"\", \"gridcolor\": \"#EBF0F8\", \"linecolor\": \"#EBF0F8\", \"automargin\": true, \"zerolinecolor\": \"#EBF0F8\", \"zerolinewidth\": 2}, \"yaxis\": {\"ticks\": \"\", \"gridcolor\": \"#EBF0F8\", \"linecolor\": \"#EBF0F8\", \"automargin\": true, \"zerolinecolor\": \"#EBF0F8\", \"zerolinewidth\": 2}, \"ternary\": {\"aaxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"linecolor\": \"#A2B1C6\"}, \"baxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"linecolor\": \"#A2B1C6\"}, \"caxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"linecolor\": \"#A2B1C6\"}, \"bgcolor\": \"white\"}, \"colorway\": [\"#636efa\", \"#EF553B\", \"#00cc96\", \"#ab63fa\", \"#19d3f3\", \"#e763fa\", \"#fecb52\", \"#ffa15a\", \"#ff6692\", \"#b6e880\"], \"hovermode\": \"closest\", \"colorscale\": {\"diverging\": [[0, \"#8e0152\"], [0.1, \"#c51b7d\"], [0.2, \"#de77ae\"], [0.3, \"#f1b6da\"], [0.4, \"#fde0ef\"], [0.5, \"#f7f7f7\"], [0.6, \"#e6f5d0\"], [0.7, \"#b8e186\"], [0.8, \"#7fbc41\"], [0.9, \"#4d9221\"], [1, \"#276419\"]], \"sequential\": [[0, \"#0508b8\"], [0.0893854748603352, \"#1910d8\"], [0.1787709497206704, \"#3c19f0\"], [0.2681564245810056, \"#6b1cfb\"], [0.3575418994413408, \"#981cfd\"], [0.44692737430167595, \"#bf1cfd\"], [0.5363128491620112, \"#dd2bfd\"], [0.6256983240223464, \"#f246fe\"], [0.7150837988826816, \"#fc67fd\"], [0.8044692737430168, \"#fe88fc\"], [0.8938547486033519, \"#fea5fd\"], [0.9832402234636871, \"#febefe\"], [1, \"#fec3fe\"]], \"sequentialminus\": [[0, \"#0508b8\"], [0.0893854748603352, \"#1910d8\"], [0.1787709497206704, \"#3c19f0\"], [0.2681564245810056, \"#6b1cfb\"], [0.3575418994413408, \"#981cfd\"], [0.44692737430167595, \"#bf1cfd\"], [0.5363128491620112, \"#dd2bfd\"], [0.6256983240223464, \"#f246fe\"], [0.7150837988826816, \"#fc67fd\"], [0.8044692737430168, \"#fe88fc\"], [0.8938547486033519, \"#fea5fd\"], [0.9832402234636871, \"#febefe\"], [1, \"#fec3fe\"]]}, \"plot_bgcolor\": \"white\", \"paper_bgcolor\": \"white\", \"shapedefaults\": {\"line\": {\"width\": 0}, \"opacity\": 0.4, \"fillcolor\": \"#506784\"}, \"annotationdefaults\": {\"arrowhead\": 0, \"arrowcolor\": \"#506784\", \"arrowwidth\": 1}}, \"themeRef\": \"PLOTLY_WHITE\"}},"
+                << std::endl
+                << "    frames: [], "
+                << std::endl
+                << "    config: {\"showLink\": true, \"linkText\": \"Export to plotly.com\", \"mapboxAccessToken\": \"pk.eyJ1IjoiY2hyaWRkeXAiLCJhIjoiY2lxMnVvdm5iMDA4dnhsbTQ5aHJzcGs0MyJ9.X9o_rzNLNesDxdra4neC_A\"}"
+                << std::endl
+                << "}";
+    }
+
+    template <typename Geometry>
+    void plot(Geometry const& geometry)
+    {
+        std::cout<<first<<std::endl;
+        if(!first)
+        {
+            detail::json::prefix_comma::apply(m_stream);
+        }
+        else
+        {
+            first = false;
+        }
+
+        json_plot(m_stream, geometry);
+    }
+};
+
+}}
+
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_IO_PLOT_LY_PLOTTER_HPP

From 48ea5f161eb45c38a76f40343059b836d0df4635 Mon Sep 17 00:00:00 2001
From: sudo-panda <kundubaidya99@gmail.com>
Date: Sun, 5 Apr 2020 23:02:42 +0530
Subject: [PATCH 2/9] [doc][ext][io] Add an example to generate json

---
 extensions/example/io/Jamfile            | 13 ++++++++++
 extensions/example/io/plotly_example.cpp | 30 ++++++++++++++++++++++++
 2 files changed, 43 insertions(+)
 create mode 100644 extensions/example/io/Jamfile
 create mode 100644 extensions/example/io/plotly_example.cpp

diff --git a/extensions/example/io/Jamfile b/extensions/example/io/Jamfile
new file mode 100644
index 0000000000..a78ef49064
--- /dev/null
+++ b/extensions/example/io/Jamfile
@@ -0,0 +1,13 @@
+# Boost.Geometry (aka GGL, Generic Geometry Library)
+#
+# Copyright (c) 2020 Baidyanath Kundu, Haldia, India.
+
+# Use, modification and distribution is subject to the Boost Software License,
+# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+project boost-geometry-extensions-io
+    : #requirements
+    ;
+
+exe plotly_example : plotly_example.cpp ;
\ No newline at end of file
diff --git a/extensions/example/io/plotly_example.cpp b/extensions/example/io/plotly_example.cpp
new file mode 100644
index 0000000000..6ff1547598
--- /dev/null
+++ b/extensions/example/io/plotly_example.cpp
@@ -0,0 +1,30 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// QuickBook Example
+
+// Copyright (c) 2013 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <iostream>
+#include <fstream>
+#include <boost/geometry.hpp>
+#include <boost/geometry/extensions/io/plotly/plotter.hpp>
+#include <boost/geometry/geometries/point_xyz.hpp>
+
+int main()
+{
+    typedef boost::geometry::model::d3::point_xyz<double> point_t;
+    
+    point_t a, b;
+    boost::geometry::assign_values(a, 1, 1, 1);
+    boost::geometry::assign_values(b, 0, 0, 0);
+
+    std::ofstream json("my_plot.json");
+    boost::geometry::json_plotter plotter(json);
+    plotter.plot(a);
+    plotter.plot(b);
+
+    return 0;
+}
\ No newline at end of file

From 8a729d0a10fd77db59c361a1ba86ef464f23b2c1 Mon Sep 17 00:00:00 2001
From: sudo-panda <kundubaidya99@gmail.com>
Date: Sat, 11 Apr 2020 03:55:08 +0530
Subject: [PATCH 3/9] [ext][plotly] Add support for - Linestring - Segment -
 Multipoint - Multilinestring

---
 .../geometry/extensions/io/plotly/plotter.hpp | 166 +++++++++++++++---
 1 file changed, 137 insertions(+), 29 deletions(-)

diff --git a/include/boost/geometry/extensions/io/plotly/plotter.hpp b/include/boost/geometry/extensions/io/plotly/plotter.hpp
index 3509308b44..b55ad3a86a 100644
--- a/include/boost/geometry/extensions/io/plotly/plotter.hpp
+++ b/include/boost/geometry/extensions/io/plotly/plotter.hpp
@@ -23,27 +23,111 @@ namespace boost { namespace geometry
 namespace detail { namespace json
 {
 
-template <typename Point>
-struct json_point_3
+template <typename Point, int Dimension>
+struct json_point
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os, 
+        Point const& p, std::string const& color)
+    {
+        os << "{ \"mode\": \"lines\", \"type\": \"" 
+           << (( Dimension > 2 ) ? "scatter3d" : "scatter" )
+           << "\"" 
+           << ", \"x\": [\"" << geometry::get<0>(p) << "\"]"
+           << ", \"y\": [\"" << geometry::get<1>(p) << "\"]"
+           << (( Dimension > 2 ) ? (", \"z\": [\"" << geometry::get<2>(p) << "\"]") : "" )
+           << ", \"marker\": {\"color\": \"" << color << "\"}}";
+    }
+};
+
+template <typename Segment, int Dimension>
+struct json_segment
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+        Segment const& segment, std::string const& color)
+    {        
+        os << "{ \"mode\": \"lines\", \"type\": \"" 
+           << (( Dimension > 2 ) ? "scatter3d" : "scatter" )
+           << "\"" 
+           << ", \"x\": [\"" << geometry::get<0, 0>(segment) << "\", \"" << geometry::get<1, 0>(segment) <<"\"]"
+           << ", \"y\": [\"" << geometry::get<0, 1>(segment) << "\", \"" << geometry::get<1, 1>(segment) <<"\"]";
+        if( Dimension == 3 )
+        {
+            os << ", \"z\": [\"" << geometry::get<0, 2>(segment) << "\", \"" << geometry::get<1, 2>(segment) << "\"]";
+        }
+        os << ", \"line\": {\"dash\": \"solid\", \"color\": \"" << color << "\", \"width\": 2}";
+    }
+};
+
+template <typename Range, int Dimension>
+struct json_range
 {
     template <typename Char, typename Traits>
     static inline void apply(std::basic_ostream<Char, Traits>& os,
-                Point const& p)
+        Range const& range, std::string const& color)
     {
-        os << "{ \"mode\": \"markers\", \"type\": \"scatter3d\", "
-            << "\"x\": [\"" << geometry::get<0>(p) << "\"],"
-            << "\"y\": [\"" << geometry::get<1>(p) << "\"],"
-            << "\"z\": [\"" << geometry::get<2>(p) << "\"]}";
+        typedef typename boost::range_iterator<Range const>::type iterator;
+
+        bool first = true;
+
+        os << "{ \"mode\": \"lines\", \"type\": \"" 
+           << (( Dimension > 2 ) ? "scatter3d" : "scatter" )
+           << "\"";
+
+        std::basic_stringstream<Char, Traits> x, y, z;
+
+        x << ", \"x\": [";
+        y << ", \"y\": [";
+        z << ( Dimension > 2 ? ", \"z\": [" : "" );
+
+        for (iterator it = boost::begin(range);
+            it != boost::end(range);
+            ++it, first = false)
+        {
+            x << (first ? "\"" : ", \"" )
+              << geometry::get<0>(*it)
+              << "\"";
+            y << (first ? "\"" : ", \"" )
+              << geometry::get<1>(*it)
+              << "\"";
+            if( Dimension > 2 ) 
+            {
+                z << (first ? "\"" : ", \"" )
+                  << geometry::get<2>(*it)
+                  << "\"";
+            }
+        }
+
+        x << "]";
+        y << "]";
+        z << ( Dimension > 2 ? "]" : "" );
+        
+        os << x.rdbuf()
+           << y.rdbuf() 
+           << z.rdbuf()
+           << ", \"line\": {\"dash\": \"solid\", \"color\": \"" << color << "\", \"width\": 2}";
     }
 };
 
-struct prefix_comma
+
+template <typename MultiGeometry, typename Policy>
+struct json_multi
 {
     template <typename Char, typename Traits>
-    static inline void apply(std::basic_ostream<Char, Traits>& os)
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+        MultiGeometry const& multi, std::string const& color)
     {
-        os << ", ";
+        for (typename boost::range_iterator<MultiGeometry const>::type
+                    it = boost::begin(multi);
+            it != boost::end(multi);
+            ++it)
+        {
+            Policy::apply(os, *it, color);
+        }
+
     }
+
 };
 
 }} // namespace detail::json
@@ -56,8 +140,7 @@ namespace dispatch
 template 
 <
     typename Geometry, 
-    typename Tag = typename tag<Geometry>::type, 
-    int Dimension = dimension<Geometry>::value
+    typename Tag = typename tag<Geometry>::type
 >
 struct json_plot
 {
@@ -69,16 +152,49 @@ struct json_plot
 };
 
 template <typename Point>
-struct json_plot<Point, point_tag, 3> : detail::json::json_point_3<Point> 
+struct json_plot<Point, point_tag> : detail::json::json_point<Point, dimension<Point>::value> {};
+
+template <typename Segment>
+struct json_plot<Segment, segment_tag> : detail::json::json_segment<Segment, dimension<Segment>::value> {};
+
+template <typename Linestring>
+struct json_plot<Linestring, linestring_tag>
+    : detail::json::json_range<Linestring,  dimension<Linestring>::value> {};
+
+template <typename MultiPoint>
+struct json_plot<MultiPoint, multi_point_tag>
+    : detail::json::json_multi
+        <
+            MultiPoint,
+            detail::json::json_point
+                <
+                    typename boost::range_value<MultiPoint>::type,
+                    dimension<MultiPoint>::value
+                >
+        >
+{};
+
+template <typename MultiLinestring>
+struct json_plot<MultiLinestring, multi_linestring_tag>
+    : detail::json::json_multi
+        <
+            MultiLinestring,
+            detail::json::json_range
+                <
+                    typename boost::range_value<MultiLinestring>::type,
+                    dimension<MultiLinestring>::value
+                >
+
+        >
 {};
 
 } // namespace dispatch
 #endif // DOXYGEN_NO_DISPATCH
 
 template <typename Geometry>
-inline void json_plot(std::ostream& stream, Geometry const& geometry)
+inline void json_plot(std::ostream& stream, Geometry const& geometry, std::string const& color)
 {
-    dispatch::json_plot<Geometry>::apply(stream, geometry);
+    dispatch::json_plot<Geometry>::apply(stream, geometry, color);
 }
 
 
@@ -100,7 +216,7 @@ class json_plotter : boost::noncopyable
 
     virtual ~json_plotter()
     {
-        m_stream << "], "
+        m_stream << "}], "
                 << std::endl
                 << "    layout: {\"scene\": {\"camera\": {\"up\": {\"x\": 0, \"y\": 0, \"z\": 1}, \"eye\": {\"x\": 0.2829440102575065, \"y\": 0.05402592432697305, \"z\": 2.14581543627592}, \"center\": {\"x\": 0, \"y\": 0, \"z\": 0}, \"projection\": {\"type\": \"perspective\"}}, \"aspectmode\": \"auto\", \"aspectratio\": {\"x\": 1, \"y\": 1, \"z\": 1}}, \"xaxis\": {\"range\": [-1, 6], \"autorange\": true}, \"yaxis\": {\"range\": [-1, 4], \"autorange\": true}, \"autosize\": true, \"template\": {\"data\": {\"bar\": [{\"type\": \"bar\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"table\": [{\"type\": \"table\", \"cells\": {\"fill\": {\"color\": \"#EBF0F8\"}, \"line\": {\"color\": \"white\"}}, \"header\": {\"fill\": {\"color\": \"#C8D4E3\"}, \"line\": {\"color\": \"white\"}}}], \"carpet\": [{\"type\": \"carpet\", \"aaxis\": {\"gridcolor\": \"#C8D4E3\", \"linecolor\": \"#C8D4E3\", \"endlinecolor\": \"#2a3f5f\", \"minorgridcolor\": \"#C8D4E3\", \"startlinecolor\": \"#2a3f5f\"}, \"baxis\": {\"gridcolor\": \"#C8D4E3\", \"linecolor\": \"#C8D4E3\", \"endlinecolor\": \"#2a3f5f\", \"minorgridcolor\": \"#C8D4E3\", \"startlinecolor\": \"#2a3f5f\"}}], \"mesh3d\": [{\"type\": \"mesh3d\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"contour\": [{\"type\": \"contour\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}, \"autocolorscale\": true}], \"heatmap\": [{\"type\": \"heatmap\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}, \"autocolorscale\": true}], \"scatter\": [{\"type\": \"scatter\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"surface\": [{\"type\": \"surface\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"heatmapgl\": [{\"type\": \"heatmapgl\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"histogram\": [{\"type\": \"histogram\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"parcoords\": [{\"line\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}, \"type\": \"parcoords\"}], \"scatter3d\": [{\"type\": \"scatter3d\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"scattergl\": [{\"type\": \"scattergl\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"choropleth\": [{\"type\": \"choropleth\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"scattergeo\": [{\"type\": \"scattergeo\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"histogram2d\": [{\"type\": \"histogram2d\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}, \"autocolorscale\": true}], \"scatterpolar\": [{\"type\": \"scatterpolar\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"contourcarpet\": [{\"type\": \"contourcarpet\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"scattercarpet\": [{\"type\": \"scattercarpet\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"scattermapbox\": [{\"type\": \"scattermapbox\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"scatterpolargl\": [{\"type\": \"scatterpolargl\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"scatterternary\": [{\"type\": \"scatterternary\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"histogram2dcontour\": [{\"type\": \"histogram2dcontour\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}, \"autocolorscale\": true}]}, \"layout\": {\"geo\": {\"bgcolor\": \"white\", \"showland\": true, \"lakecolor\": \"white\", \"landcolor\": \"white\", \"showlakes\": true, \"subunitcolor\": \"#C8D4E3\"}, \"font\": {\"color\": \"#2a3f5f\"}, \"polar\": {\"bgcolor\": \"white\", \"radialaxis\": {\"ticks\": \"\", \"gridcolor\": \"#EBF0F8\", \"linecolor\": \"#EBF0F8\"}, \"angularaxis\": {\"ticks\": \"\", \"gridcolor\": \"#EBF0F8\", \"linecolor\": \"#EBF0F8\"}}, \"scene\": {\"xaxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"gridwidth\": 2, \"linecolor\": \"#EBF0F8\", \"zerolinecolor\": \"#EBF0F8\", \"showbackground\": true, \"backgroundcolor\": \"white\"}, \"yaxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"gridwidth\": 2, \"linecolor\": \"#EBF0F8\", \"zerolinecolor\": \"#EBF0F8\", \"showbackground\": true, \"backgroundcolor\": \"white\"}, \"zaxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"gridwidth\": 2, \"linecolor\": \"#EBF0F8\", \"zerolinecolor\": \"#EBF0F8\", \"showbackground\": true, \"backgroundcolor\": \"white\"}}, \"title\": {\"x\": 0.05}, \"xaxis\": {\"ticks\": \"\", \"gridcolor\": \"#EBF0F8\", \"linecolor\": \"#EBF0F8\", \"automargin\": true, \"zerolinecolor\": \"#EBF0F8\", \"zerolinewidth\": 2}, \"yaxis\": {\"ticks\": \"\", \"gridcolor\": \"#EBF0F8\", \"linecolor\": \"#EBF0F8\", \"automargin\": true, \"zerolinecolor\": \"#EBF0F8\", \"zerolinewidth\": 2}, \"ternary\": {\"aaxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"linecolor\": \"#A2B1C6\"}, \"baxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"linecolor\": \"#A2B1C6\"}, \"caxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"linecolor\": \"#A2B1C6\"}, \"bgcolor\": \"white\"}, \"colorway\": [\"#636efa\", \"#EF553B\", \"#00cc96\", \"#ab63fa\", \"#19d3f3\", \"#e763fa\", \"#fecb52\", \"#ffa15a\", \"#ff6692\", \"#b6e880\"], \"hovermode\": \"closest\", \"colorscale\": {\"diverging\": [[0, \"#8e0152\"], [0.1, \"#c51b7d\"], [0.2, \"#de77ae\"], [0.3, \"#f1b6da\"], [0.4, \"#fde0ef\"], [0.5, \"#f7f7f7\"], [0.6, \"#e6f5d0\"], [0.7, \"#b8e186\"], [0.8, \"#7fbc41\"], [0.9, \"#4d9221\"], [1, \"#276419\"]], \"sequential\": [[0, \"#0508b8\"], [0.0893854748603352, \"#1910d8\"], [0.1787709497206704, \"#3c19f0\"], [0.2681564245810056, \"#6b1cfb\"], [0.3575418994413408, \"#981cfd\"], [0.44692737430167595, \"#bf1cfd\"], [0.5363128491620112, \"#dd2bfd\"], [0.6256983240223464, \"#f246fe\"], [0.7150837988826816, \"#fc67fd\"], [0.8044692737430168, \"#fe88fc\"], [0.8938547486033519, \"#fea5fd\"], [0.9832402234636871, \"#febefe\"], [1, \"#fec3fe\"]], \"sequentialminus\": [[0, \"#0508b8\"], [0.0893854748603352, \"#1910d8\"], [0.1787709497206704, \"#3c19f0\"], [0.2681564245810056, \"#6b1cfb\"], [0.3575418994413408, \"#981cfd\"], [0.44692737430167595, \"#bf1cfd\"], [0.5363128491620112, \"#dd2bfd\"], [0.6256983240223464, \"#f246fe\"], [0.7150837988826816, \"#fc67fd\"], [0.8044692737430168, \"#fe88fc\"], [0.8938547486033519, \"#fea5fd\"], [0.9832402234636871, \"#febefe\"], [1, \"#fec3fe\"]]}, \"plot_bgcolor\": \"white\", \"paper_bgcolor\": \"white\", \"shapedefaults\": {\"line\": {\"width\": 0}, \"opacity\": 0.4, \"fillcolor\": \"#506784\"}, \"annotationdefaults\": {\"arrowhead\": 0, \"arrowcolor\": \"#506784\", \"arrowwidth\": 1}}, \"themeRef\": \"PLOTLY_WHITE\"}},"
                 << std::endl
@@ -112,23 +228,15 @@ class json_plotter : boost::noncopyable
     }
 
     template <typename Geometry>
-    void plot(Geometry const& geometry)
+    void plot(Geometry const& geometry, std::string const& color)
     {
-        std::cout<<first<<std::endl;
-        if(!first)
-        {
-            detail::json::prefix_comma::apply(m_stream);
-        }
-        else
-        {
-            first = false;
-        }
-
-        json_plot(m_stream, geometry);
+        m_stream << ( first ? "" : ", " );
+        first = false;
+        json_plot(m_stream, geometry, color);
     }
 };
 
-}}
+}} // namespace boost::geometry
 
 
 #endif // BOOST_GEOMETRY_EXTENSIONS_IO_PLOT_LY_PLOTTER_HPP

From 0979b759414cdcccdfc2b3c7d5484bc47c6d0ac6 Mon Sep 17 00:00:00 2001
From: sudo-panda <kundubaidya99@gmail.com>
Date: Sat, 11 Apr 2020 03:56:08 +0530
Subject: [PATCH 4/9] [doc][ext][plotly] Modify example to provide color

---
 extensions/example/io/plotly_example.cpp | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/extensions/example/io/plotly_example.cpp b/extensions/example/io/plotly_example.cpp
index 6ff1547598..956726568a 100644
--- a/extensions/example/io/plotly_example.cpp
+++ b/extensions/example/io/plotly_example.cpp
@@ -17,14 +17,15 @@ int main()
 {
     typedef boost::geometry::model::d3::point_xyz<double> point_t;
     
-    point_t a, b;
-    boost::geometry::assign_values(a, 1, 1, 1);
-    boost::geometry::assign_values(b, 0, 0, 0);
+    boost::geometry::model::linestring<point_t> a;
+
+    boost::geometry::append(a, point_t(0, 0, 0));
+    boost::geometry::append(a, point_t(0, 1, 2));
+    boost::geometry::append(a, point_t(1, 2, 3));
 
     std::ofstream json("my_plot.json");
     boost::geometry::json_plotter plotter(json);
-    plotter.plot(a);
-    plotter.plot(b);
+    plotter.plot(a, "rgb(5, 200, 64)");
 
     return 0;
 }
\ No newline at end of file

From e53311474670e383f2ba6ecd022e79afebdb1b56 Mon Sep 17 00:00:00 2001
From: sudo-panda <kundubaidya99@gmail.com>
Date: Fri, 24 Apr 2020 22:50:49 +0530
Subject: [PATCH 5/9] [ext][io]Add color class and support for polygon

---
 .../geometry/extensions/io/plotly/plotter.hpp | 332 +++++++++++++-----
 1 file changed, 247 insertions(+), 85 deletions(-)

diff --git a/include/boost/geometry/extensions/io/plotly/plotter.hpp b/include/boost/geometry/extensions/io/plotly/plotter.hpp
index b55ad3a86a..6af5c8af9c 100644
--- a/include/boost/geometry/extensions/io/plotly/plotter.hpp
+++ b/include/boost/geometry/extensions/io/plotly/plotter.hpp
@@ -19,55 +19,153 @@
 namespace boost { namespace geometry
 {
 
+class plotly_color
+{
+public:
+    inline plotly_color(int r, int g, int b)
+        : m_r(r), m_g(g), m_b(b)
+    {}
+
+    inline std::string rgb()
+    {
+        return "rgb(" + 
+               boost::lexical_cast<std::string>(m_r) + 
+               "," + 
+               boost::lexical_cast<std::string>(m_g) + 
+               "," + 
+               boost::lexical_cast<std::string>(m_b) + 
+               ")";
+    }
+
+    inline std::string rgba(float a)
+    {
+        return "rgba(" + 
+               boost::lexical_cast<std::string>(m_r) + 
+               "," + 
+               boost::lexical_cast<std::string>(m_g) + 
+               "," + 
+               boost::lexical_cast<std::string>(m_b) + 
+               "," +
+               boost::lexical_cast<std::string>(a) +
+               ")";
+    }
+private:
+    int m_r;
+    int m_g;
+    int m_b;
+};
+
 #ifndef DOXYGEN_NO_DETAIL
-namespace detail { namespace json
+namespace detail { namespace plotly
+{
+
+template <typename P, int D>
+struct stream_coordinate
+{
+    static inline void apply(std::vector<std::string>& ss, P const& p, bool first)
+    {
+        stream_coordinate<P, D-1>::apply(ss, p, first);
+    }
+};
+
+template <typename P>
+struct stream_coordinate<P,3>
+{
+    static inline void apply(std::vector<std::string>& ss, P const& p, bool first)
+    {
+        ss[2] += (first ? "\"z\": [\"" : ", \"") + boost::lexical_cast<std::string>(get<2>(p)) + "\"";
+        stream_coordinate<P, 2>::apply(ss, p, first);
+    }
+};
+
+template <typename P>
+struct stream_coordinate<P,2>
+{
+    static inline void apply(std::vector<std::string>& ss, P const& p, bool first)
+    {
+        ss[1] += (first ? "\"y\": [\"" : ", \"") + boost::lexical_cast<std::string>(get<1>(p)) + "\"";
+        stream_coordinate<P, 1>::apply(ss, p, first);
+    }
+};
+
+template <typename P>
+struct stream_coordinate<P,1>
 {
+    static inline void apply(std::vector<std::string>& ss, P const& p, bool first)
+    {
+        ss[0] += (first ? "\"x\": [\"" : ", \"") + boost::lexical_cast<std::string>(get<0>(p)) + "\"";
+    }
+};
 
+/*!
+\brief Stream points as plotly style json
+*/
 template <typename Point, int Dimension>
-struct json_point
+struct plotly_point
 {
     template <typename Char, typename Traits>
     static inline void apply(std::basic_ostream<Char, Traits>& os, 
-        Point const& p, std::string const& color)
+        Point const& p, boost::geometry::plotly_color& c)
     {
         os << "{ \"mode\": \"lines\", \"type\": \"" 
            << (( Dimension > 2 ) ? "scatter3d" : "scatter" )
-           << "\"" 
-           << ", \"x\": [\"" << geometry::get<0>(p) << "\"]"
-           << ", \"y\": [\"" << geometry::get<1>(p) << "\"]"
-           << (( Dimension > 2 ) ? (", \"z\": [\"" << geometry::get<2>(p) << "\"]") : "" )
-           << ", \"marker\": {\"color\": \"" << color << "\"}}";
+           << "\"";
+
+        std::vector<std::string> ss(Dimension);
+        stream_coordinate<Point, Dimension>::apply(ss, p, true);
+
+        for(std::vector<std::string>::iterator it=ss.begin();
+            it!=ss.end(); it++)
+        {
+            os << ", " << *it << "]";
+        }
+
+        os << ", \"marker\": {\"color\": \"" << c.rgb() << "\"}, \"showlegend\": false}";
     }
 };
 
 template <typename Segment, int Dimension>
-struct json_segment
+struct plotly_segment
 {
+    typedef typename point_type<Segment>::type point_type;
+
     template <typename Char, typename Traits>
     static inline void apply(std::basic_ostream<Char, Traits>& os,
-        Segment const& segment, std::string const& color)
+        Segment const& segment, boost::geometry::plotly_color& c)
     {        
         os << "{ \"mode\": \"lines\", \"type\": \"" 
            << (( Dimension > 2 ) ? "scatter3d" : "scatter" )
-           << "\"" 
-           << ", \"x\": [\"" << geometry::get<0, 0>(segment) << "\", \"" << geometry::get<1, 0>(segment) <<"\"]"
-           << ", \"y\": [\"" << geometry::get<0, 1>(segment) << "\", \"" << geometry::get<1, 1>(segment) <<"\"]";
-        if( Dimension == 3 )
+           << "\"";
+
+        typedef boost::array<point_type, 2> sequence;
+
+        sequence points;
+        geometry::detail::assign_point_from_index<0>(segment, points[0]);
+        geometry::detail::assign_point_from_index<1>(segment, points[1]);
+
+        std::vector<std::string> ss(Dimension);
+        stream_coordinate<point_type, Dimension>::apply(ss, points[0], true);
+        stream_coordinate<point_type, Dimension>::apply(ss, points[1], false);
+
+        for(std::vector<std::string>::iterator it=ss.begin();
+            it!=ss.end(); it++)
         {
-            os << ", \"z\": [\"" << geometry::get<0, 2>(segment) << "\", \"" << geometry::get<1, 2>(segment) << "\"]";
+            os << ", " << *it << "]";
         }
-        os << ", \"line\": {\"dash\": \"solid\", \"color\": \"" << color << "\", \"width\": 2}";
+
+        os << ", \"marker\": {\"color\": \"" << c.rgb() 
+           << "\"}, \"line\": {\"dash\": \"solid\", \"color\": \"" << c.rgb() << "\", \"width\": 2}, \"showlegend\": false}";
     }
 };
 
 template <typename Range, int Dimension>
-struct json_range
+struct plotly_range
 {
     template <typename Char, typename Traits>
     static inline void apply(std::basic_ostream<Char, Traits>& os,
-        Range const& range, std::string const& color)
+        Range const& range, boost::geometry::plotly_color& c)
     {
-        typedef typename boost::range_iterator<Range const>::type iterator;
+        typedef typename boost::range_iterator<Range const>::type iterator_t;
 
         bool first = true;
 
@@ -75,62 +173,124 @@ struct json_range
            << (( Dimension > 2 ) ? "scatter3d" : "scatter" )
            << "\"";
 
-        std::basic_stringstream<Char, Traits> x, y, z;
-
-        x << ", \"x\": [";
-        y << ", \"y\": [";
-        z << ( Dimension > 2 ? ", \"z\": [" : "" );
+        std::vector<std::string> ss(Dimension);
 
-        for (iterator it = boost::begin(range);
+        for (iterator_t it = boost::begin(range);
             it != boost::end(range);
             ++it, first = false)
         {
-            x << (first ? "\"" : ", \"" )
-              << geometry::get<0>(*it)
-              << "\"";
-            y << (first ? "\"" : ", \"" )
-              << geometry::get<1>(*it)
-              << "\"";
-            if( Dimension > 2 ) 
-            {
-                z << (first ? "\"" : ", \"" )
-                  << geometry::get<2>(*it)
-                  << "\"";
-            }
+            stream_coordinate<point_type, Dimension>::apply(ss, *it, first);
         }
 
-        x << "]";
-        y << "]";
-        z << ( Dimension > 2 ? "]" : "" );
+        for(std::vector<std::string>::iterator it=ss.begin();
+            it!=ss.end(); it++)
+        {
+            os << ", " << *it << "]";
+        }
         
-        os << x.rdbuf()
-           << y.rdbuf() 
-           << z.rdbuf()
-           << ", \"line\": {\"dash\": \"solid\", \"color\": \"" << color << "\", \"width\": 2}";
+        os << ", \"line\": {\"dash\": \"solid\", \"color\": \"" << c.rgb() << "\", \"width\": 2}, \"showlegend\": false}";
+    }
+private:
+    typedef typename boost::range_value<Range>::type point_type;
+};
+
+template <typename Polygon, int Dimension>
+struct plotly_poly
+{
+    template <typename Char, typename Traits>
+    static inline void apply(std::basic_ostream<Char, Traits>& os,
+        Polygon const& polygon, boost::geometry::plotly_color& c)
+    {
+        typedef typename geometry::ring_type<Polygon>::type ring_t;
+        typedef typename boost::range_iterator<ring_t const>::type iterator_t;
+
+        typedef typename boost::range_value<ring_t>::type point_type;
+        
+        bool first = true;
+        os << "{ \"mode\": \"lines\", \"type\": \"" 
+           << (( Dimension > 2 ) ? "scatter3d" : "scatter" )
+           << "\"";
+
+        std::vector<std::string> ss(Dimension);
+
+        ring_t const& ring = geometry::exterior_ring(polygon);
+        for (iterator_t it = boost::begin(ring);
+            it != boost::end(ring);
+            ++it, first = false)
+        {
+            stream_coordinate<point_type, Dimension>::apply(ss, *it, first);
+        }
+        
+        for(std::vector<std::string>::iterator it=ss.begin();
+            it!=ss.end(); it++)
+        {
+            os << ", " << *it << "]";
+        }
+
+        os << ", \"line\": {\"dash\": \"solid\", \"color\": \"" << c.rgb() << "\", \"width\": 2}"
+           << ", \"fill\": \"tozerox\", \"fillcolor\": \"" << c.rgba(0.5) << "\", \"showlegend\": false}";
+        
+        // Inner rings:
+        boost::geometry::plotly_color w(255,255,255);
+        typename interior_return_type<Polygon const>::type
+            rings = interior_rings(polygon);
+        for (typename detail::interior_iterator<Polygon const>::type
+                rit = boost::begin(rings); rit != boost::end(rings); ++rit)
+        {
+
+            first = true;
+            os << ", { \"mode\": \"lines\", \"type\": \"" 
+                << (( Dimension > 2 ) ? "scatter3d" : "scatter" )
+                << "\"";
+
+            for(std::vector<std::string>::iterator it=ss.begin();
+                it!=ss.end(); it++)
+            {
+                *it = "";
+            }
+
+            for (typename detail::interior_ring_iterator<Polygon const>::type
+                    it = boost::begin(*rit); it != boost::end(*rit);
+                ++it, first = false)
+            {
+                stream_coordinate<point_type, Dimension>::apply(ss, *it, first);
+            }
+
+            for(std::vector<std::string>::iterator it=ss.begin();
+            it!=ss.end(); it++)
+            {
+                os << ", " << *it << "]";
+            }
+
+            os << ", \"line\": {\"dash\": \"solid\", \"color\": \"" << c.rgb() << "\", \"width\": 2}"
+               << ", \"fill\": \"tozerox\", \"fillcolor\": \"" << w.rgba(0.5) << "\", \"showlegend\": false}";
+        }
     }
 };
 
 
 template <typename MultiGeometry, typename Policy>
-struct json_multi
+struct plotly_multi
 {
     template <typename Char, typename Traits>
     static inline void apply(std::basic_ostream<Char, Traits>& os,
-        MultiGeometry const& multi, std::string const& color)
+        MultiGeometry const& multi, boost::geometry::plotly_color& c)
     {
         for (typename boost::range_iterator<MultiGeometry const>::type
                     it = boost::begin(multi);
             it != boost::end(multi);
             ++it)
         {
-            Policy::apply(os, *it, color);
+            Policy::apply(os, *it, c);
         }
 
     }
 
 };
 
-}} // namespace detail::json
+
+
+}} // namespace detail::plotly
 #endif // DOXYGEN_NO_DETAIL
 
 #ifndef DOXYGEN_NO_DISPATCH
@@ -142,7 +302,7 @@ template
     typename Geometry, 
     typename Tag = typename tag<Geometry>::type
 >
-struct json_plot
+struct plotly_plot
 {
     BOOST_MPL_ASSERT_MSG
         (
@@ -152,21 +312,26 @@ struct json_plot
 };
 
 template <typename Point>
-struct json_plot<Point, point_tag> : detail::json::json_point<Point, dimension<Point>::value> {};
+struct plotly_plot<Point, point_tag> : detail::plotly::plotly_point<Point, dimension<Point>::value> {};
 
 template <typename Segment>
-struct json_plot<Segment, segment_tag> : detail::json::json_segment<Segment, dimension<Segment>::value> {};
+struct plotly_plot<Segment, segment_tag> : detail::plotly::plotly_segment<Segment, dimension<Segment>::value> {};
 
 template <typename Linestring>
-struct json_plot<Linestring, linestring_tag>
-    : detail::json::json_range<Linestring,  dimension<Linestring>::value> {};
+struct plotly_plot<Linestring, linestring_tag>
+    : detail::plotly::plotly_range<Linestring,  dimension<Linestring>::value> {};
+
+
+template <typename Polygon>
+struct plotly_plot<Polygon, polygon_tag>
+    : detail::plotly::plotly_poly<Polygon,  dimension<Polygon>::value> {};
 
 template <typename MultiPoint>
-struct json_plot<MultiPoint, multi_point_tag>
-    : detail::json::json_multi
+struct plotly_plot<MultiPoint, multi_point_tag>
+    : detail::plotly::plotly_multi
         <
             MultiPoint,
-            detail::json::json_point
+            detail::plotly::plotly_point
                 <
                     typename boost::range_value<MultiPoint>::type,
                     dimension<MultiPoint>::value
@@ -175,11 +340,11 @@ struct json_plot<MultiPoint, multi_point_tag>
 {};
 
 template <typename MultiLinestring>
-struct json_plot<MultiLinestring, multi_linestring_tag>
-    : detail::json::json_multi
+struct plotly_plot<MultiLinestring, multi_linestring_tag>
+    : detail::plotly::plotly_multi
         <
             MultiLinestring,
-            detail::json::json_range
+            detail::plotly::plotly_range
                 <
                     typename boost::range_value<MultiLinestring>::type,
                     dimension<MultiLinestring>::value
@@ -191,49 +356,46 @@ struct json_plot<MultiLinestring, multi_linestring_tag>
 } // namespace dispatch
 #endif // DOXYGEN_NO_DISPATCH
 
-template <typename Geometry>
-inline void json_plot(std::ostream& stream, Geometry const& geometry, std::string const& color)
+
+template <typename Geometry,typename Char, typename Traits>
+inline void plotly_plot(std::basic_ostream<Char, Traits>& stream, Geometry const& geometry, boost::geometry::plotly_color& c)
 {
-    dispatch::json_plot<Geometry>::apply(stream, geometry, color);
+    dispatch::plotly_plot<Geometry>::apply(stream, geometry, c);
 }
 
-
-class json_plotter : boost::noncopyable
+template <typename Stream>
+class plotly_plotter : boost::noncopyable
 {
-    std::ostream& m_stream;
-    bool first;
-
 public:
-
-    json_plotter(std::ostream& stream)
-        : m_stream(stream)
+    template <typename ...Ts>
+    inline plotly_plotter(Ts &&... params)
+        : m_stream(std::forward<Ts>(params)...)
     {
-        m_stream << "{"
-                << std::endl
-                << "    data: [";
+        m_stream << "{\n"
+                 << "    data: [";
         first = true;
     }
 
-    virtual ~json_plotter()
+    inline ~plotly_plotter()
     {
-        m_stream << "}], "
-                << std::endl
-                << "    layout: {\"scene\": {\"camera\": {\"up\": {\"x\": 0, \"y\": 0, \"z\": 1}, \"eye\": {\"x\": 0.2829440102575065, \"y\": 0.05402592432697305, \"z\": 2.14581543627592}, \"center\": {\"x\": 0, \"y\": 0, \"z\": 0}, \"projection\": {\"type\": \"perspective\"}}, \"aspectmode\": \"auto\", \"aspectratio\": {\"x\": 1, \"y\": 1, \"z\": 1}}, \"xaxis\": {\"range\": [-1, 6], \"autorange\": true}, \"yaxis\": {\"range\": [-1, 4], \"autorange\": true}, \"autosize\": true, \"template\": {\"data\": {\"bar\": [{\"type\": \"bar\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"table\": [{\"type\": \"table\", \"cells\": {\"fill\": {\"color\": \"#EBF0F8\"}, \"line\": {\"color\": \"white\"}}, \"header\": {\"fill\": {\"color\": \"#C8D4E3\"}, \"line\": {\"color\": \"white\"}}}], \"carpet\": [{\"type\": \"carpet\", \"aaxis\": {\"gridcolor\": \"#C8D4E3\", \"linecolor\": \"#C8D4E3\", \"endlinecolor\": \"#2a3f5f\", \"minorgridcolor\": \"#C8D4E3\", \"startlinecolor\": \"#2a3f5f\"}, \"baxis\": {\"gridcolor\": \"#C8D4E3\", \"linecolor\": \"#C8D4E3\", \"endlinecolor\": \"#2a3f5f\", \"minorgridcolor\": \"#C8D4E3\", \"startlinecolor\": \"#2a3f5f\"}}], \"mesh3d\": [{\"type\": \"mesh3d\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"contour\": [{\"type\": \"contour\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}, \"autocolorscale\": true}], \"heatmap\": [{\"type\": \"heatmap\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}, \"autocolorscale\": true}], \"scatter\": [{\"type\": \"scatter\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"surface\": [{\"type\": \"surface\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"heatmapgl\": [{\"type\": \"heatmapgl\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"histogram\": [{\"type\": \"histogram\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"parcoords\": [{\"line\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}, \"type\": \"parcoords\"}], \"scatter3d\": [{\"type\": \"scatter3d\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"scattergl\": [{\"type\": \"scattergl\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"choropleth\": [{\"type\": \"choropleth\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"scattergeo\": [{\"type\": \"scattergeo\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"histogram2d\": [{\"type\": \"histogram2d\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}, \"autocolorscale\": true}], \"scatterpolar\": [{\"type\": \"scatterpolar\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"contourcarpet\": [{\"type\": \"contourcarpet\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"scattercarpet\": [{\"type\": \"scattercarpet\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"scattermapbox\": [{\"type\": \"scattermapbox\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"scatterpolargl\": [{\"type\": \"scatterpolargl\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"scatterternary\": [{\"type\": \"scatterternary\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"histogram2dcontour\": [{\"type\": \"histogram2dcontour\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}, \"autocolorscale\": true}]}, \"layout\": {\"geo\": {\"bgcolor\": \"white\", \"showland\": true, \"lakecolor\": \"white\", \"landcolor\": \"white\", \"showlakes\": true, \"subunitcolor\": \"#C8D4E3\"}, \"font\": {\"color\": \"#2a3f5f\"}, \"polar\": {\"bgcolor\": \"white\", \"radialaxis\": {\"ticks\": \"\", \"gridcolor\": \"#EBF0F8\", \"linecolor\": \"#EBF0F8\"}, \"angularaxis\": {\"ticks\": \"\", \"gridcolor\": \"#EBF0F8\", \"linecolor\": \"#EBF0F8\"}}, \"scene\": {\"xaxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"gridwidth\": 2, \"linecolor\": \"#EBF0F8\", \"zerolinecolor\": \"#EBF0F8\", \"showbackground\": true, \"backgroundcolor\": \"white\"}, \"yaxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"gridwidth\": 2, \"linecolor\": \"#EBF0F8\", \"zerolinecolor\": \"#EBF0F8\", \"showbackground\": true, \"backgroundcolor\": \"white\"}, \"zaxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"gridwidth\": 2, \"linecolor\": \"#EBF0F8\", \"zerolinecolor\": \"#EBF0F8\", \"showbackground\": true, \"backgroundcolor\": \"white\"}}, \"title\": {\"x\": 0.05}, \"xaxis\": {\"ticks\": \"\", \"gridcolor\": \"#EBF0F8\", \"linecolor\": \"#EBF0F8\", \"automargin\": true, \"zerolinecolor\": \"#EBF0F8\", \"zerolinewidth\": 2}, \"yaxis\": {\"ticks\": \"\", \"gridcolor\": \"#EBF0F8\", \"linecolor\": \"#EBF0F8\", \"automargin\": true, \"zerolinecolor\": \"#EBF0F8\", \"zerolinewidth\": 2}, \"ternary\": {\"aaxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"linecolor\": \"#A2B1C6\"}, \"baxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"linecolor\": \"#A2B1C6\"}, \"caxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"linecolor\": \"#A2B1C6\"}, \"bgcolor\": \"white\"}, \"colorway\": [\"#636efa\", \"#EF553B\", \"#00cc96\", \"#ab63fa\", \"#19d3f3\", \"#e763fa\", \"#fecb52\", \"#ffa15a\", \"#ff6692\", \"#b6e880\"], \"hovermode\": \"closest\", \"colorscale\": {\"diverging\": [[0, \"#8e0152\"], [0.1, \"#c51b7d\"], [0.2, \"#de77ae\"], [0.3, \"#f1b6da\"], [0.4, \"#fde0ef\"], [0.5, \"#f7f7f7\"], [0.6, \"#e6f5d0\"], [0.7, \"#b8e186\"], [0.8, \"#7fbc41\"], [0.9, \"#4d9221\"], [1, \"#276419\"]], \"sequential\": [[0, \"#0508b8\"], [0.0893854748603352, \"#1910d8\"], [0.1787709497206704, \"#3c19f0\"], [0.2681564245810056, \"#6b1cfb\"], [0.3575418994413408, \"#981cfd\"], [0.44692737430167595, \"#bf1cfd\"], [0.5363128491620112, \"#dd2bfd\"], [0.6256983240223464, \"#f246fe\"], [0.7150837988826816, \"#fc67fd\"], [0.8044692737430168, \"#fe88fc\"], [0.8938547486033519, \"#fea5fd\"], [0.9832402234636871, \"#febefe\"], [1, \"#fec3fe\"]], \"sequentialminus\": [[0, \"#0508b8\"], [0.0893854748603352, \"#1910d8\"], [0.1787709497206704, \"#3c19f0\"], [0.2681564245810056, \"#6b1cfb\"], [0.3575418994413408, \"#981cfd\"], [0.44692737430167595, \"#bf1cfd\"], [0.5363128491620112, \"#dd2bfd\"], [0.6256983240223464, \"#f246fe\"], [0.7150837988826816, \"#fc67fd\"], [0.8044692737430168, \"#fe88fc\"], [0.8938547486033519, \"#fea5fd\"], [0.9832402234636871, \"#febefe\"], [1, \"#fec3fe\"]]}, \"plot_bgcolor\": \"white\", \"paper_bgcolor\": \"white\", \"shapedefaults\": {\"line\": {\"width\": 0}, \"opacity\": 0.4, \"fillcolor\": \"#506784\"}, \"annotationdefaults\": {\"arrowhead\": 0, \"arrowcolor\": \"#506784\", \"arrowwidth\": 1}}, \"themeRef\": \"PLOTLY_WHITE\"}},"
-                << std::endl
-                << "    frames: [], "
-                << std::endl
-                << "    config: {\"showLink\": true, \"linkText\": \"Export to plotly.com\", \"mapboxAccessToken\": \"pk.eyJ1IjoiY2hyaWRkeXAiLCJhIjoiY2lxMnVvdm5iMDA4dnhsbTQ5aHJzcGs0MyJ9.X9o_rzNLNesDxdra4neC_A\"}"
-                << std::endl
-                << "}";
+        m_stream << "], \n"
+                 << "    layout: {\"scene\": {\"camera\": {\"up\": {\"x\": 0, \"y\": 0, \"z\": 1}, \"eye\": {\"x\": 0.2829440102575065, \"y\": 0.05402592432697305, \"z\": 2.14581543627592}, \"center\": {\"x\": 0, \"y\": 0, \"z\": 0}, \"projection\": {\"type\": \"perspective\"}}, \"aspectmode\": \"auto\", \"aspectratio\": {\"x\": 1, \"y\": 1, \"z\": 1}}, \"xaxis\": {\"range\": [-1, 6], \"autorange\": true}, \"yaxis\": {\"range\": [-1, 4], \"autorange\": true}, \"autosize\": true, \"template\": {\"data\": {\"bar\": [{\"type\": \"bar\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"table\": [{\"type\": \"table\", \"cells\": {\"fill\": {\"color\": \"#EBF0F8\"}, \"line\": {\"color\": \"white\"}}, \"header\": {\"fill\": {\"color\": \"#C8D4E3\"}, \"line\": {\"color\": \"white\"}}}], \"carpet\": [{\"type\": \"carpet\", \"aaxis\": {\"gridcolor\": \"#C8D4E3\", \"linecolor\": \"#C8D4E3\", \"endlinecolor\": \"#2a3f5f\", \"minorgridcolor\": \"#C8D4E3\", \"startlinecolor\": \"#2a3f5f\"}, \"baxis\": {\"gridcolor\": \"#C8D4E3\", \"linecolor\": \"#C8D4E3\", \"endlinecolor\": \"#2a3f5f\", \"minorgridcolor\": \"#C8D4E3\", \"startlinecolor\": \"#2a3f5f\"}}], \"mesh3d\": [{\"type\": \"mesh3d\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"contour\": [{\"type\": \"contour\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}, \"autocolorscale\": true}], \"heatmap\": [{\"type\": \"heatmap\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}, \"autocolorscale\": true}], \"scatter\": [{\"type\": \"scatter\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"surface\": [{\"type\": \"surface\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"heatmapgl\": [{\"type\": \"heatmapgl\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"histogram\": [{\"type\": \"histogram\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"parcoords\": [{\"line\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}, \"type\": \"parcoords\"}], \"scatter3d\": [{\"type\": \"scatter3d\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"scattergl\": [{\"type\": \"scattergl\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"choropleth\": [{\"type\": \"choropleth\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"scattergeo\": [{\"type\": \"scattergeo\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"histogram2d\": [{\"type\": \"histogram2d\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}, \"autocolorscale\": true}], \"scatterpolar\": [{\"type\": \"scatterpolar\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"contourcarpet\": [{\"type\": \"contourcarpet\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}], \"scattercarpet\": [{\"type\": \"scattercarpet\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"scattermapbox\": [{\"type\": \"scattermapbox\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"scatterpolargl\": [{\"type\": \"scatterpolargl\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"scatterternary\": [{\"type\": \"scatterternary\", \"marker\": {\"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}}}], \"histogram2dcontour\": [{\"type\": \"histogram2dcontour\", \"colorbar\": {\"ticks\": \"\", \"outlinewidth\": 0}, \"autocolorscale\": true}]}, \"layout\": {\"geo\": {\"bgcolor\": \"white\", \"showland\": true, \"lakecolor\": \"white\", \"landcolor\": \"white\", \"showlakes\": true, \"subunitcolor\": \"#C8D4E3\"}, \"font\": {\"color\": \"#2a3f5f\"}, \"polar\": {\"bgcolor\": \"white\", \"radialaxis\": {\"ticks\": \"\", \"gridcolor\": \"#EBF0F8\", \"linecolor\": \"#EBF0F8\"}, \"angularaxis\": {\"ticks\": \"\", \"gridcolor\": \"#EBF0F8\", \"linecolor\": \"#EBF0F8\"}}, \"scene\": {\"xaxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"gridwidth\": 2, \"linecolor\": \"#EBF0F8\", \"zerolinecolor\": \"#EBF0F8\", \"showbackground\": true, \"backgroundcolor\": \"white\"}, \"yaxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"gridwidth\": 2, \"linecolor\": \"#EBF0F8\", \"zerolinecolor\": \"#EBF0F8\", \"showbackground\": true, \"backgroundcolor\": \"white\"}, \"zaxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"gridwidth\": 2, \"linecolor\": \"#EBF0F8\", \"zerolinecolor\": \"#EBF0F8\", \"showbackground\": true, \"backgroundcolor\": \"white\"}}, \"title\": {\"x\": 0.05}, \"xaxis\": {\"ticks\": \"\", \"gridcolor\": \"#EBF0F8\", \"linecolor\": \"#EBF0F8\", \"automargin\": true, \"zerolinecolor\": \"#EBF0F8\", \"zerolinewidth\": 2}, \"yaxis\": {\"ticks\": \"\", \"gridcolor\": \"#EBF0F8\", \"linecolor\": \"#EBF0F8\", \"automargin\": true, \"zerolinecolor\": \"#EBF0F8\", \"zerolinewidth\": 2}, \"ternary\": {\"aaxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"linecolor\": \"#A2B1C6\"}, \"baxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"linecolor\": \"#A2B1C6\"}, \"caxis\": {\"ticks\": \"\", \"gridcolor\": \"#DFE8F3\", \"linecolor\": \"#A2B1C6\"}, \"bgcolor\": \"white\"}, \"colorway\": [\"#636efa\", \"#EF553B\", \"#00cc96\", \"#ab63fa\", \"#19d3f3\", \"#e763fa\", \"#fecb52\", \"#ffa15a\", \"#ff6692\", \"#b6e880\"], \"hovermode\": \"closest\", \"colorscale\": {\"diverging\": [[0, \"#8e0152\"], [0.1, \"#c51b7d\"], [0.2, \"#de77ae\"], [0.3, \"#f1b6da\"], [0.4, \"#fde0ef\"], [0.5, \"#f7f7f7\"], [0.6, \"#e6f5d0\"], [0.7, \"#b8e186\"], [0.8, \"#7fbc41\"], [0.9, \"#4d9221\"], [1, \"#276419\"]], \"sequential\": [[0, \"#0508b8\"], [0.0893854748603352, \"#1910d8\"], [0.1787709497206704, \"#3c19f0\"], [0.2681564245810056, \"#6b1cfb\"], [0.3575418994413408, \"#981cfd\"], [0.44692737430167595, \"#bf1cfd\"], [0.5363128491620112, \"#dd2bfd\"], [0.6256983240223464, \"#f246fe\"], [0.7150837988826816, \"#fc67fd\"], [0.8044692737430168, \"#fe88fc\"], [0.8938547486033519, \"#fea5fd\"], [0.9832402234636871, \"#febefe\"], [1, \"#fec3fe\"]], \"sequentialminus\": [[0, \"#0508b8\"], [0.0893854748603352, \"#1910d8\"], [0.1787709497206704, \"#3c19f0\"], [0.2681564245810056, \"#6b1cfb\"], [0.3575418994413408, \"#981cfd\"], [0.44692737430167595, \"#bf1cfd\"], [0.5363128491620112, \"#dd2bfd\"], [0.6256983240223464, \"#f246fe\"], [0.7150837988826816, \"#fc67fd\"], [0.8044692737430168, \"#fe88fc\"], [0.8938547486033519, \"#fea5fd\"], [0.9832402234636871, \"#febefe\"], [1, \"#fec3fe\"]]}, \"plot_bgcolor\": \"white\", \"paper_bgcolor\": \"white\", \"shapedefaults\": {\"line\": {\"width\": 0}, \"opacity\": 0.4, \"fillcolor\": \"#506784\"}, \"annotationdefaults\": {\"arrowhead\": 0, \"arrowcolor\": \"#506784\", \"arrowwidth\": 1}}, \"themeRef\": \"PLOTLY_WHITE\"}},\n"
+                 << "    frames: [], \n"
+                 << "    config: {\"showLink\": true, \"linkText\": \"Export to plotly.com\", \"mapboxAccessToken\": \"pk.eyJ1IjoiY2hyaWRkeXAiLCJhIjoiY2lxMnVvdm5iMDA4dnhsbTQ5aHJzcGs0MyJ9.X9o_rzNLNesDxdra4neC_A\"}\n"
+                 << "}";
     }
 
     template <typename Geometry>
-    void plot(Geometry const& geometry, std::string const& color)
+    void plot(Geometry const& geometry, plotly_color && c)
     {
         m_stream << ( first ? "" : ", " );
         first = false;
-        json_plot(m_stream, geometry, color);
+        plotly_plot(m_stream, geometry, c);
     }
+
+private:
+    Stream m_stream;
+    bool first;
 };
 
 }} // namespace boost::geometry

From a7ce2af149382e468c2f2d23a9df0c561119917d Mon Sep 17 00:00:00 2001
From: sudo-panda <kundubaidya99@gmail.com>
Date: Fri, 24 Apr 2020 22:53:10 +0530
Subject: [PATCH 6/9] [doc][ext][io] Change ex to check prev commit

---
 extensions/example/io/plotly_example.cpp | 31 ++++++++++++++++--------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/extensions/example/io/plotly_example.cpp b/extensions/example/io/plotly_example.cpp
index 956726568a..1fb7760f26 100644
--- a/extensions/example/io/plotly_example.cpp
+++ b/extensions/example/io/plotly_example.cpp
@@ -11,21 +11,32 @@
 #include <fstream>
 #include <boost/geometry.hpp>
 #include <boost/geometry/extensions/io/plotly/plotter.hpp>
-#include <boost/geometry/geometries/point_xyz.hpp>
+#include <boost/geometry/geometries/point_xy.hpp>
+
+namespace bg = boost::geometry;
 
 int main()
 {
-    typedef boost::geometry::model::d3::point_xyz<double> point_t;
-    
-    boost::geometry::model::linestring<point_t> a;
+    typedef bg::model::point<double, 2, bg::cs::cartesian> point_t;
+    typedef bg::model::polygon<point_t> polygon_t;
 
-    boost::geometry::append(a, point_t(0, 0, 0));
-    boost::geometry::append(a, point_t(0, 1, 2));
-    boost::geometry::append(a, point_t(1, 2, 3));
+    polygon_t poly1;
 
-    std::ofstream json("my_plot.json");
-    boost::geometry::json_plotter plotter(json);
-    plotter.plot(a, "rgb(5, 200, 64)");
+    bg::append(poly1.outer(), point_t(0.0, 0.0));
+    bg::append(poly1.outer(), point_t(0.0, 5.0));
+    bg::append(poly1.outer(), point_t(5.0, 5.0));
+    bg::append(poly1.outer(), point_t(5.0, 0.0));
+    bg::append(poly1.outer(), point_t(0.0, 0.0));
+
+    poly1.inners().resize(1);
+    bg::append(poly1.inners()[0], point_t(1.0, 1.0));
+    bg::append(poly1.inners()[0], point_t(4.0, 1.0));
+    bg::append(poly1.inners()[0], point_t(4.0, 4.0));
+    bg::append(poly1.inners()[0], point_t(1.0, 4.0));
+    bg::append(poly1.inners()[0], point_t(1.0, 1.0));
+    
+    bg::plotly_plotter<std::ofstream> plotter("my_plot.json");
+    plotter.plot(poly1, bg::plotly_color(255, 39, 0));
 
     return 0;
 }
\ No newline at end of file

From 99c8e84a498a95ed6ca5cbe4b8d4078a3dffe172 Mon Sep 17 00:00:00 2001
From: sudo-panda <kundubaidya99@gmail.com>
Date: Mon, 11 May 2020 23:34:19 +0530
Subject: [PATCH 7/9] [ext][io][plotly] add support for geographic tag

---
 .../geometry/extensions/io/plotly/plotter.hpp | 175 ++++++++++++++----
 1 file changed, 140 insertions(+), 35 deletions(-)

diff --git a/include/boost/geometry/extensions/io/plotly/plotter.hpp b/include/boost/geometry/extensions/io/plotly/plotter.hpp
index 6af5c8af9c..f245fea5b0 100644
--- a/include/boost/geometry/extensions/io/plotly/plotter.hpp
+++ b/include/boost/geometry/extensions/io/plotly/plotter.hpp
@@ -59,48 +59,80 @@ class plotly_color
 namespace detail { namespace plotly
 {
 
-template <typename P, int D>
+template <typename P, int D, typename T>
 struct stream_coordinate
 {
     static inline void apply(std::vector<std::string>& ss, P const& p, bool first)
     {
-        stream_coordinate<P, D-1>::apply(ss, p, first);
+        stream_coordinate<P, D-1, T>::apply(ss, p, first);
     }
 };
 
-template <typename P>
-struct stream_coordinate<P,3>
+template <typename P, typename T>
+struct stream_coordinate<P,3,T>
 {
     static inline void apply(std::vector<std::string>& ss, P const& p, bool first)
     {
-        ss[2] += (first ? "\"z\": [\"" : ", \"") + boost::lexical_cast<std::string>(get<2>(p)) + "\"";
-        stream_coordinate<P, 2>::apply(ss, p, first);
+        ss[2] += (first ? T::d3() : ", \"") + boost::lexical_cast<std::string>(get<2>(p)) + "\"";
+        stream_coordinate<P, 2, T>::apply(ss, p, first);
     }
 };
 
-template <typename P>
-struct stream_coordinate<P,2>
+template <typename P, typename T>
+struct stream_coordinate<P,2,T>
 {
     static inline void apply(std::vector<std::string>& ss, P const& p, bool first)
     {
-        ss[1] += (first ? "\"y\": [\"" : ", \"") + boost::lexical_cast<std::string>(get<1>(p)) + "\"";
-        stream_coordinate<P, 1>::apply(ss, p, first);
+        ss[1] += (first ? T::d2() : ", \"") + boost::lexical_cast<std::string>(get<1>(p)) + "\"";
+        stream_coordinate<P, 1, T>::apply(ss, p, first);
     }
 };
 
-template <typename P>
-struct stream_coordinate<P,1>
+template <typename P, typename T>
+struct stream_coordinate<P,1,T>
 {
     static inline void apply(std::vector<std::string>& ss, P const& p, bool first)
     {
-        ss[0] += (first ? "\"x\": [\"" : ", \"") + boost::lexical_cast<std::string>(get<0>(p)) + "\"";
+        ss[0] += (first ? T::d1() : ", \"") + boost::lexical_cast<std::string>(get<0>(p)) + "\"";
     }
 };
 
+
+struct type_cartesian_2
+{
+    static inline const char* plot_type() { return "scatter"; }
+    static inline const char* fill_type() { return "tozerox"; }
+    static inline const char* d1() { return "\"x\": [\""; }
+    static inline const char* d2() { return "\"y\": [\""; }
+};
+
+
+struct type_cartesian_3
+{
+    static inline const char* plot_type() { return "scatter3d"; }
+    static inline const char* fill_type() { return "tozerox"; }
+    static inline const char* d1() { return "\"x\": [\""; }
+    static inline const char* d2() { return "\"y\": [\""; }
+    static inline const char* d3() { return "\"z\": [\""; }
+};
+
+struct type_geographic
+{
+    static inline const char* plot_type() { return "scattermapbox"; }
+    static inline const char* fill_type() { return "toself"; }
+    static inline const char* d1() { return "\"lat\": [\""; }
+    static inline const char* d2() { return "\"lon\": [\""; }
+};
+
 /*!
 \brief Stream points as plotly style json
 */
-template <typename Point, int Dimension>
+template 
+<
+    typename Point, 
+    int Dimension,
+    typename PlotType
+>
 struct plotly_point
 {
     template <typename Char, typename Traits>
@@ -108,11 +140,11 @@ struct plotly_point
         Point const& p, boost::geometry::plotly_color& c)
     {
         os << "{ \"mode\": \"lines\", \"type\": \"" 
-           << (( Dimension > 2 ) ? "scatter3d" : "scatter" )
+           << PlotType::plot_type()
            << "\"";
 
         std::vector<std::string> ss(Dimension);
-        stream_coordinate<Point, Dimension>::apply(ss, p, true);
+        stream_coordinate<Point, Dimension, PlotType>::apply(ss, p, true);
 
         for(std::vector<std::string>::iterator it=ss.begin();
             it!=ss.end(); it++)
@@ -124,7 +156,12 @@ struct plotly_point
     }
 };
 
-template <typename Segment, int Dimension>
+template 
+<
+    typename Segment, 
+    int Dimension,
+    typename PlotType
+>
 struct plotly_segment
 {
     typedef typename point_type<Segment>::type point_type;
@@ -134,7 +171,7 @@ struct plotly_segment
         Segment const& segment, boost::geometry::plotly_color& c)
     {        
         os << "{ \"mode\": \"lines\", \"type\": \"" 
-           << (( Dimension > 2 ) ? "scatter3d" : "scatter" )
+           << PlotType::plot_type()
            << "\"";
 
         typedef boost::array<point_type, 2> sequence;
@@ -144,8 +181,8 @@ struct plotly_segment
         geometry::detail::assign_point_from_index<1>(segment, points[1]);
 
         std::vector<std::string> ss(Dimension);
-        stream_coordinate<point_type, Dimension>::apply(ss, points[0], true);
-        stream_coordinate<point_type, Dimension>::apply(ss, points[1], false);
+        stream_coordinate<point_type, Dimension, PlotType>::apply(ss, points[0], true);
+        stream_coordinate<point_type, Dimension, PlotType>::apply(ss, points[1], false);
 
         for(std::vector<std::string>::iterator it=ss.begin();
             it!=ss.end(); it++)
@@ -158,7 +195,12 @@ struct plotly_segment
     }
 };
 
-template <typename Range, int Dimension>
+template 
+<
+    typename Range, 
+    int Dimension,
+    typename PlotType
+>
 struct plotly_range
 {
     template <typename Char, typename Traits>
@@ -170,7 +212,7 @@ struct plotly_range
         bool first = true;
 
         os << "{ \"mode\": \"lines\", \"type\": \"" 
-           << (( Dimension > 2 ) ? "scatter3d" : "scatter" )
+           << PlotType::plot_type()
            << "\"";
 
         std::vector<std::string> ss(Dimension);
@@ -179,7 +221,7 @@ struct plotly_range
             it != boost::end(range);
             ++it, first = false)
         {
-            stream_coordinate<point_type, Dimension>::apply(ss, *it, first);
+            stream_coordinate<point_type, Dimension, PlotType>::apply(ss, *it, first);
         }
 
         for(std::vector<std::string>::iterator it=ss.begin();
@@ -194,7 +236,12 @@ struct plotly_range
     typedef typename boost::range_value<Range>::type point_type;
 };
 
-template <typename Polygon, int Dimension>
+template 
+<
+    typename Polygon, 
+    int Dimension,
+    typename PlotType
+>
 struct plotly_poly
 {
     template <typename Char, typename Traits>
@@ -208,7 +255,7 @@ struct plotly_poly
         
         bool first = true;
         os << "{ \"mode\": \"lines\", \"type\": \"" 
-           << (( Dimension > 2 ) ? "scatter3d" : "scatter" )
+           << PlotType::plot_type()
            << "\"";
 
         std::vector<std::string> ss(Dimension);
@@ -218,7 +265,7 @@ struct plotly_poly
             it != boost::end(ring);
             ++it, first = false)
         {
-            stream_coordinate<point_type, Dimension>::apply(ss, *it, first);
+            stream_coordinate<point_type, Dimension, PlotType>::apply(ss, *it, first);
         }
         
         for(std::vector<std::string>::iterator it=ss.begin();
@@ -228,7 +275,7 @@ struct plotly_poly
         }
 
         os << ", \"line\": {\"dash\": \"solid\", \"color\": \"" << c.rgb() << "\", \"width\": 2}"
-           << ", \"fill\": \"tozerox\", \"fillcolor\": \"" << c.rgba(0.5) << "\", \"showlegend\": false}";
+           << ", \"fill\": \""<<  PlotType::fill_type() <<"\", \"fillcolor\": \"" << c.rgba(0.5) << "\", \"showlegend\": false}";
         
         // Inner rings:
         boost::geometry::plotly_color w(255,255,255);
@@ -253,7 +300,7 @@ struct plotly_poly
                     it = boost::begin(*rit); it != boost::end(*rit);
                 ++it, first = false)
             {
-                stream_coordinate<point_type, Dimension>::apply(ss, *it, first);
+                stream_coordinate<point_type, Dimension, PlotType>::apply(ss, *it, first);
             }
 
             for(std::vector<std::string>::iterator it=ss.begin();
@@ -263,7 +310,7 @@ struct plotly_poly
             }
 
             os << ", \"line\": {\"dash\": \"solid\", \"color\": \"" << c.rgb() << "\", \"width\": 2}"
-               << ", \"fill\": \"tozerox\", \"fillcolor\": \"" << w.rgba(0.5) << "\", \"showlegend\": false}";
+               << ", \"fill\": \""<<  PlotType::fill_type() <<"\", \"fillcolor\": \"" << w.rgba(0.5) << "\", \"showlegend\": false}";
         }
     }
 };
@@ -297,6 +344,36 @@ struct plotly_multi
 namespace dispatch
 {
 
+template
+<
+    typename Geometry,
+    typename Tag = typename cs_tag<Geometry>::type,
+    int Dimension = dimension<Geometry>::value
+>
+struct plotly_type
+{
+    BOOST_MPL_ASSERT_MSG
+        (
+            false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_CS_TAG_OR_DIMENSION
+            , (Geometry)
+        );
+};
+
+template <typename Geometry>
+struct plotly_type<Geometry, cartesian_tag, 2>
+    : detail::plotly::type_cartesian_2
+{};
+
+template <typename Geometry>
+struct plotly_type<Geometry, cartesian_tag, 3>
+    : detail::plotly::type_cartesian_2
+{};
+
+template <typename Geometry, int Dimension>
+struct plotly_type<Geometry, geographic_tag, Dimension>
+    : detail::plotly::type_geographic
+{};
+
 template 
 <
     typename Geometry, 
@@ -312,19 +389,45 @@ struct plotly_plot
 };
 
 template <typename Point>
-struct plotly_plot<Point, point_tag> : detail::plotly::plotly_point<Point, dimension<Point>::value> {};
+struct plotly_plot<Point, point_tag> 
+    : detail::plotly::plotly_point
+        <
+            Point, 
+            dimension<Point>::value,
+            plotly_type<Point>
+        > 
+{};
 
 template <typename Segment>
-struct plotly_plot<Segment, segment_tag> : detail::plotly::plotly_segment<Segment, dimension<Segment>::value> {};
+struct plotly_plot<Segment, segment_tag> 
+    : detail::plotly::plotly_segment
+        <
+            Segment, 
+            dimension<Segment>::value,
+            plotly_type<Segment>
+        > 
+{};
 
 template <typename Linestring>
 struct plotly_plot<Linestring, linestring_tag>
-    : detail::plotly::plotly_range<Linestring,  dimension<Linestring>::value> {};
+    : detail::plotly::plotly_range
+        <
+            Linestring,  
+            dimension<Linestring>::value,
+            plotly_type<Linestring>
+        > 
+{};
 
 
 template <typename Polygon>
 struct plotly_plot<Polygon, polygon_tag>
-    : detail::plotly::plotly_poly<Polygon,  dimension<Polygon>::value> {};
+    : detail::plotly::plotly_poly
+        <
+            Polygon,  
+            dimension<Polygon>::value,
+            plotly_type<Polygon>
+        > 
+{};
 
 template <typename MultiPoint>
 struct plotly_plot<MultiPoint, multi_point_tag>
@@ -334,7 +437,8 @@ struct plotly_plot<MultiPoint, multi_point_tag>
             detail::plotly::plotly_point
                 <
                     typename boost::range_value<MultiPoint>::type,
-                    dimension<MultiPoint>::value
+                    dimension<MultiPoint>::value,
+                    plotly_type<MultiPoint>
                 >
         >
 {};
@@ -347,7 +451,8 @@ struct plotly_plot<MultiLinestring, multi_linestring_tag>
             detail::plotly::plotly_range
                 <
                     typename boost::range_value<MultiLinestring>::type,
-                    dimension<MultiLinestring>::value
+                    dimension<MultiLinestring>::value,
+                    plotly_type<MultiLinestring>
                 >
 
         >

From 8560b71803c34e1b748c4f62811cdcf0fa8f202c Mon Sep 17 00:00:00 2001
From: sudo-panda <kundubaidya99@gmail.com>
Date: Mon, 11 May 2020 23:35:42 +0530
Subject: [PATCH 8/9] [doc][ext][io] example for geographic tag

---
 extensions/example/io/plotly_example.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/extensions/example/io/plotly_example.cpp b/extensions/example/io/plotly_example.cpp
index 1fb7760f26..762cbc7894 100644
--- a/extensions/example/io/plotly_example.cpp
+++ b/extensions/example/io/plotly_example.cpp
@@ -17,7 +17,7 @@ namespace bg = boost::geometry;
 
 int main()
 {
-    typedef bg::model::point<double, 2, bg::cs::cartesian> point_t;
+    typedef bg::model::point<double, 2, bg::cs::geographic<bg::degree>> point_t;
     typedef bg::model::polygon<point_t> polygon_t;
 
     polygon_t poly1;

From 2230068921028b2e25cf762237cf33101a428a96 Mon Sep 17 00:00:00 2001
From: sudo-panda <kundubaidya99@gmail.com>
Date: Tue, 12 May 2020 00:01:53 +0530
Subject: [PATCH 9/9] [ext][io][plotly] minor bug fix

---
 include/boost/geometry/extensions/io/plotly/plotter.hpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/boost/geometry/extensions/io/plotly/plotter.hpp b/include/boost/geometry/extensions/io/plotly/plotter.hpp
index f245fea5b0..7c0b706a7e 100644
--- a/include/boost/geometry/extensions/io/plotly/plotter.hpp
+++ b/include/boost/geometry/extensions/io/plotly/plotter.hpp
@@ -275,7 +275,7 @@ struct plotly_poly
         }
 
         os << ", \"line\": {\"dash\": \"solid\", \"color\": \"" << c.rgb() << "\", \"width\": 2}"
-           << ", \"fill\": \""<<  PlotType::fill_type() <<"\", \"fillcolor\": \"" << c.rgba(0.5) << "\", \"showlegend\": false}";
+           << ", \"fill\": \""<<  PlotType::fill_type() <<"\", \"fillcolor\": \"" << c.rgba(0.3) << "\", \"showlegend\": false}";
         
         // Inner rings:
         boost::geometry::plotly_color w(255,255,255);
@@ -287,7 +287,7 @@ struct plotly_poly
 
             first = true;
             os << ", { \"mode\": \"lines\", \"type\": \"" 
-                << (( Dimension > 2 ) ? "scatter3d" : "scatter" )
+                << PlotType::plot_type()
                 << "\"";
 
             for(std::vector<std::string>::iterator it=ss.begin();
@@ -310,7 +310,7 @@ struct plotly_poly
             }
 
             os << ", \"line\": {\"dash\": \"solid\", \"color\": \"" << c.rgb() << "\", \"width\": 2}"
-               << ", \"fill\": \""<<  PlotType::fill_type() <<"\", \"fillcolor\": \"" << w.rgba(0.5) << "\", \"showlegend\": false}";
+               << ", \"fill\": \""<<  PlotType::fill_type() <<"\", \"fillcolor\": \"" << w.rgba(0.2) << "\", \"showlegend\": false}";
         }
     }
 };