Skip to content

Commit

Permalink
bug fix embed widget (#345)
Browse files Browse the repository at this point in the history
* bug fix embed widget, the previous code still encountered problem with CORS
* fix travis error
* embed widget link for qgis-server and geoserver backend
* embed widget link and add copy button
* refactor map projection on the frontend into django views

fix #152
  • Loading branch information
boney-bun authored Oct 18, 2017
1 parent 55483f3 commit 8ae1950
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 20 deletions.
53 changes: 53 additions & 0 deletions geonode/maps/templates/leaflet_maps/map_embed_widget.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<div class="map-container">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.3/leaflet.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.3/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.15/proj4-src.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var wmsLayer = null;

var map = L.map('map').setView([{{ resource.center_y }}, {{ resource.center_x }}], {{ resource.zoom }});
var osm = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
});
map.addLayer(osm);

var bbox = {{ map_bbox }};

zoom_to_box(map, bbox);

{% for layer in map_layers %}
var layer_url = '{{ layer.ows_url }}';
var options = {
format: 'image/png',
transparent: true,
layers: '{{ layer.name }}',
opacity: 0.8
};
if (layer_url.includes('{z}') && layer_url.includes('{y}') && layer_url.includes('{x}')) {
wmsLayer = L.tileLayer(layer_url, options);
}
else {
wmsLayer = L.tileLayer.wms(layer_url, options);
}
if (wmsLayer != null) {
map.addLayer(wmsLayer);
}
{% endfor %}
});

function zoom_to_box(map, bbox) {
var bounds = [
[bbox[1], bbox[0]],
[bbox[3], bbox[2]]
];
}
</script>
<style type="text/css">
#map {
height: 800px;
}
</style>
<div id="map"></div>
</div>
41 changes: 23 additions & 18 deletions geonode/maps/templates/maps/map_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -289,26 +289,11 @@ <h4 class="modal-title" id="myModalLabel">{% trans "Embed Iframe" %}</h4>
<h4 class="modal-title" id="myModalLabel">{% trans "Embed Widget" %}</h4>
</div>
<div class="modal-body">
<p>To embed this map, the first step is to import a library and a js function to the html's head section on your site:</p>
<p style="font-weight: bold; font-size: small;">
<p>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"&gt;&lt;/script&gt;</p>
<p>&lt;script type="text/javascript"&gt;</p>
<ul style="list-style: none;">
<li>$.get("{{ SITEURL|slice:":-1" }}{% url "map_embed" resource.id %}", function(data) {</li>
<li>&nbsp;&nbsp;&nbsp;if(data) {</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$("#embed-map-link").html(data)</li>
<li>&nbsp;&nbsp;&nbsp;}</li>
<li>});</li>
</ul>
<p>&lt;/script&gt;</p>
</p>

<p>Finally, insert the div tag below into a location suits your need in the html's body</p>
<p style="font-weight: bold;font-size: small;">
&lt;div id="embed-map-link"&gt;&lt;/div&gt;
</p>
<p>To embed this map, copy the following code snippet into your own page:</p>
<pre id="embed-widget-body" style="font-size: 0.5em"></pre>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-clipboard-target="#embed-widget-body">{% trans "Copy to Clipboard" %}</button>
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Close" %}</button>
</div>
</div>
Expand All @@ -328,7 +313,27 @@ <h4 class="modal-title" id="myModalLabel">{% trans "Embed Widget" %}</h4>
{% overall_rating resource "map" as the_map_rating %}
{% endif %}
{% include 'rating.html' %}
<script type="text/javascript" src="{{ STATIC_URL}}geonode/js/utils/clipboard.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
post_url = '{% url 'map_embed_widget' resource.id %}';
var formatted_data = "";
$.post(post_url, function (data) {
data = data.split("\n");
data_row = data.length;
for (var i=0; i < data_row;i++) {
formatted_data += data[i] + "\n";
}
$('#embed-widget-body').text(formatted_data);
});
});
var clipboard = new Clipboard('.btn');
clipboard.on('success', function(e) {
alert("Code copied");
});
clipboard.on('error', function(e) {
alert("Oops.. something went wrong");
});
$(function() {

{% verbatim %}
Expand Down
1 change: 1 addition & 0 deletions geonode/maps/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
url(r'^(?P<mapid>[^/]+)/metadata$', 'map_metadata', name='map_metadata'),
url(r'^(?P<mapid>[^/]+)/metadata_advanced$', 'map_metadata_advanced', name='map_metadata_advanced'),
url(r'^(?P<mapid>[^/]+)/embed$', map_embed, name='map_embed'),
url(r'^(?P<mapid>[^/]+)/embed_widget$', 'map_embed_widget', name='map_embed_widget'),
url(r'^(?P<mapid>[^/]+)/history$', 'ajax_snapshot_history'),
url(r'^(?P<mapid>\d+)/thumbnail$', map_thumbnail, name='map_thumbnail'),
url(r'^(?P<mapid>[^/]+)/(?P<snapshot>[A-Za-z0-9_\-]+)/view$', 'map_view'),
Expand Down
75 changes: 74 additions & 1 deletion geonode/maps/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from django.core.serializers.json import DjangoJSONEncoder
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotAllowed, HttpResponseServerError
from django.http.response import HttpResponseBadRequest
from django.shortcuts import render_to_response, get_object_or_404
from django.shortcuts import render_to_response, get_object_or_404, render
from django.conf import settings
from django.template import RequestContext
from django.utils.translation import ugettext as _
Expand Down Expand Up @@ -356,6 +356,79 @@ def map_embed(
}))


def map_embed_widget(request, mapid,
template='leaflet_maps/map_embed_widget.html'):
"""Display code snippet for embedding widget.
:param request: The request from the frontend.
:type request: HttpRequest
:param mapid: The id of the map.
:type mapid: String
:return: formatted code.
"""

map_obj = _resolve_map(request,
mapid,
'base.view_resourcebase',
_PERMISSION_MSG_VIEW)
map_bbox = map_obj.bbox_string.split(',')

map_layers = MapLayer.objects.filter(
map_id=mapid).order_by('stack_order')
layers = []
for layer in map_layers:
if layer.group != 'background':
layers.append(layer)

if map_obj.srid != 'EPSG:3857':
map_bbox = [float(coord) for coord in map_bbox]
else:
map_bbox = llbbox_to_mercator([float(coord) for coord in map_bbox])

if map_bbox is not None:
minx, miny, maxx, maxy = [float(coord) for coord in map_bbox]
x = (minx + maxx) / 2
y = (miny + maxy) / 2

if getattr(settings, 'DEFAULT_MAP_CRS') == "EPSG:3857":
center = list((x, y))
else:
center = list(forward_mercator((x, y)))

if center[1] == float('-inf'):
center[1] = 0

BBOX_DIFFERENCE_THRESHOLD = 1e-5

# Check if the bbox is invalid
valid_x = (maxx - minx) ** 2 > BBOX_DIFFERENCE_THRESHOLD
valid_y = (maxy - miny) ** 2 > BBOX_DIFFERENCE_THRESHOLD

if valid_x:
width_zoom = math.log(360 / abs(maxx - minx), 2)
else:
width_zoom = 15

if valid_y:
height_zoom = math.log(360 / abs(maxy - miny), 2)
else:
height_zoom = 15

map_obj.center_x = center[0]
map_obj.center_y = center[1]
map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

context = {
'resource': map_obj,
'map_bbox': map_bbox,
'map_layers': layers
}
message = render(request, template, context)
return HttpResponse(message)


# MAPS VIEWER #


Expand Down
2 changes: 1 addition & 1 deletion geonode/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,7 @@

# default map projection
# Note: If set to EPSG:4326, then only EPSG:4326 basemaps will work.
DEFAULT_MAP_CRS = "EPSG:900913"
DEFAULT_MAP_CRS = "EPSG:3857"

# Where should newly created maps be focused?
DEFAULT_MAP_CENTER = (0, 0)
Expand Down
7 changes: 7 additions & 0 deletions geonode/static/geonode/js/utils/clipboard.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 8ae1950

Please sign in to comment.