create HTML div for Leaflet map
Added by Pedro Vicente over 7 years ago
I'm trying to generate a Leaflet map, similar to WGoogleMap
The Leaflet API requires an HTML
to be rendered, so how I accomplish that, to generate a div dynamically, or load
an existing HTML too, don't know if possible?
the WT API has functions for
DomElement createElement
but it does not have many Javascript/HTML examples of how to use
basically I want to create this HTML page
<!DOCTYPE html>
<html>
<head>
<title>Map</title>
<link rel="stylesheet" href="leaflet.css" />
<script src="leaflet.js"></script>
<style>
#map { height: 100%;}
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var layer_base = L.tileLayer(
'http://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}',{
maxZoom: 20,
subdomains:['mt0','mt1','mt2','mt3']
}
);
var map = new L.Map('map', {
center: new L.LatLng(38.9072, -77.0369),
zoom: 8,
layers: [layer_base]
});
</script>
</body>
</html>
so I came out with
namespace Wt
{
LOGGER("WLeaflet");
///////////////////////////////////////////////////////////////////////////////////////
//WLeaflet::WLeaflet
///////////////////////////////////////////////////////////////////////////////////////
WLeaflet::WLeaflet(WContainerWidget *parent)
{
setImplementation(new WContainerWidget());
if (parent)
{
parent->addWidget(this);
}
this->addCssRule("#map_id" + id(), "position:absolute; top:0; bottom:0; width:100%;");
Wt::WApplication * app = Wt::WApplication::instance();
app->useStyleSheet(Wt::WCssStyleSheet(Wt::WLink("https://unpkg.com/leaflet@1.0.3/dist/leaflet.css")));
const std::string mburi = "https://unpkg.com/leaflet@1.0.3/dist/leaflet.js";
app->require(mburi, "leaflet");
}
///////////////////////////////////////////////////////////////////////////////////////
//WLeaflet::~WLeaflet
///////////////////////////////////////////////////////////////////////////////////////
WLeaflet::~WLeaflet()
{
}
///////////////////////////////////////////////////////////////////////////////////////
//WLeaflet::render
///////////////////////////////////////////////////////////////////////////////////////
void WLeaflet::render(WFlags<RenderFlag> flags)
{
if (flags & Wt::RenderFull)
{
Wt::WApplication * app = Wt::WApplication::instance();
Wt::WString initFunction = app->javaScriptClass() + ".init_mapbox_" + id();
Wt::WStringStream stream;
stream
<< "{ " << initFunction.toUTF8() << " = function() {\n"
<< " var self = " << jsRef() << ";\n"
<< " if (!self) {\n"
<< " setTimeout(" << initFunction.toUTF8() << ", 0);\n"
<< " }\n";
stream
<< " var layer_base = L.tileLayer(\n"
<< " 'http://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}',{\n"
<< " maxZoom: 20,\n"
<< " subdomains:['mt0','mt1','mt2','mt3']\n"
<< " }\n"
<< " );\n";
stream
<< " var map = new L.Map('map_id', {\n"
<< " center: new L.LatLng(38.9072, -77.0369),\n"
<< " zoom: 8,\n"
<< " layers: [layer_base]\n"
<< " });\n";
stream
<< " setTimeout(function(){ delete " << initFunction.toUTF8() << ";}, 0)};\n"
<< "}\n"
<< initFunction.toUTF8() << "();\n";
LOG_INFO(stream.str());
app->doJavaScript(stream.str());
}
Wt::WCompositeWidget::render(flags);
}
}
but the Leaflet API gives an error on the browser saying
Error: Map container not found.
which I think is because of the missing div
so , how can the div be done ?
Replies (2)
RE: create HTML div for Leaflet map - Added by Pedro Vicente over 7 years ago
I got the leaflet map displayed by setting the
to the "self" variable as done in WGoogleMap
stream
<< " var map = new L.Map(self, {\n"
however the map is displayed with a very small height as seen in the attached file
It seems Leaflet requires this CSS
html, body {
height: 100%;
}
as explained here
https://stackoverflow.com/questions/16543446/how-to-make-leaflet-map-height-variable
how can this be done with WT ?
the complete code
#include "Wt/WLogger"
#include <Wt/WLeaflet.hh>
#include <Wt/WApplication>
#include <Wt/WContainerWidget>
#include "web/WebUtils.h"
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <string>
#include <utility>
#include <iostream>
#include <cmath>
namespace Wt
{
LOGGER("WLeaflet");
///////////////////////////////////////////////////////////////////////////////////////
//WLeaflet::WLeaflet
///////////////////////////////////////////////////////////////////////////////////////
WLeaflet::WLeaflet(WContainerWidget *parent)
{
setImplementation(new WContainerWidget());
if (parent)
{
parent->addWidget(this);
}
this->addCssRule("#" + id(), "position:absolute; top:0; bottom:0; right: 0; left: 0; width: 100%; height: 100%");
Wt::WApplication * app = Wt::WApplication::instance();
app->useStyleSheet(Wt::WCssStyleSheet(Wt::WLink("https://unpkg.com/leaflet@1.0.3/dist/leaflet.css")));
const std::string mburi = "https://unpkg.com/leaflet@1.0.3/dist/leaflet.js";
app->require(mburi, "leaflet");
}
///////////////////////////////////////////////////////////////////////////////////////
//WLeaflet::~WLeaflet
///////////////////////////////////////////////////////////////////////////////////////
WLeaflet::~WLeaflet()
{
}
///////////////////////////////////////////////////////////////////////////////////////
//WLeaflet::render
///////////////////////////////////////////////////////////////////////////////////////
void WLeaflet::render(WFlags<RenderFlag> flags)
{
if (flags & Wt::RenderFull)
{
Wt::WApplication * app = Wt::WApplication::instance();
Wt::WString initFunction = app->javaScriptClass() + ".init_leaflet_" + id();
Wt::WStringStream stream;
stream
<< "{ " << initFunction.toUTF8() << " = function() {\n"
<< " var self = " << jsRef() << ";\n"
<< " if (!self) {\n"
<< " setTimeout(" << initFunction.toUTF8() << ", 0);\n"
<< " }\n";
stream
<< " var layer_base = L.tileLayer(\n"
<< " 'http://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}',{\n"
<< " maxZoom: 20,\n"
<< " subdomains:['mt0','mt1','mt2','mt3']\n"
<< " }\n"
<< " );\n";
stream
<< " var map = new L.Map(self, {\n"
<< " center: new L.LatLng(38.9072, -77.0369),\n"
<< " zoom: 8,\n"
<< " layers: [layer_base]\n"
<< " });\n";
stream
<< " setTimeout(function(){ delete " << initFunction.toUTF8() << ";}, 0)};\n"
<< "}\n"
<< initFunction.toUTF8() << "();\n";
LOG_INFO(stream.str());
app->doJavaScript(stream.str());
}
Wt::WCompositeWidget::render(flags);
}
}
Untitled.png (81.9 KB) Untitled.png |
RE: create HTML div for Leaflet map - Added by Pedro Vicente over 7 years ago
after a bit of research (read: intuitive guess) adding CSS to HTML can be done with
this->addCssRule("html", "height: 100%;");
this->addCssRule("body", "height: 100%;");
for
html, body {
height: 100%;
}