Verified Commit 87fee4e8 authored by Elger Jonker's avatar Elger Jonker

bugfixes

parent d7237a8d
Pipeline #39337836 passed with stages
in 19 minutes and 21 seconds
......@@ -458,7 +458,7 @@ class OrganizationSubmissionAdmin(ImportExportModelAdmin, admin.ModelAdmin):
organization=new_org,
geojsontype="Point",
area=osm.organization_address_geocoded,
edit_area=osm.organization_address_geocoded,
edit_area={"type": "Point", "coordinates": osm.organization_address_geocoded},
created_on=timezone.now(),
creation_metadata="Accepted organization submission"
)
......
......@@ -155,8 +155,8 @@ class OrganisationSubmissionForm(forms.Form):
organization_type_name = forms.ModelChoiceField(
queryset=OrganizationType.objects.all(),
widget=autocomplete.ModelSelect2(url='/game/autocomplete/organization-type-autocomplete/'),
label="Type / Map Layer",
help_text="Types are rendered as separate layers on the map."
label="Map Layer",
help_text="On what layer this organization should be shown."
)
organization_evidence = forms.CharField(
......@@ -235,7 +235,7 @@ class OrganisationSubmissionForm(forms.Form):
organization_type_name=organization_type_name,
organization_wikipedia=organization_wikipedia,
organization_wikidata_code=organization_wikidata,
organization_address_geocoded=[lng, lat],
organization_address_geocoded="[%s, %s]" % (lng, lat),
organization_country=organization_country,
suggested_urls=organization_suggested_urls,
added_on=timezone.now(),
......
# Generated by Django 2.1.3 on 2018-12-07 11:42
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('game', '0018_auto_20181206_1039'),
]
operations = [
migrations.AlterField(
model_name='organizationsubmission',
name='organization_address_geocoded',
field=models.CharField(blank=True, help_text='Automatic geocoded organization address.',
max_length=5000, null=True),
),
]
......@@ -4,7 +4,6 @@ from django.db import models
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
from django_countries.fields import CountryField
from djgeojson.fields import GeoJSONField
from failmap.organizations.models import Organization, Url
......@@ -143,7 +142,8 @@ class OrganizationSubmission(models.Model):
help_text="Sources of information about this organization."
)
organization_address_geocoded = GeoJSONField(
# geojsonfields require the type defined in the geojson. We don't store geojson but just a coordinate.
organization_address_geocoded = models.CharField(
max_length=5000,
null=True,
blank=True,
......
......@@ -7,18 +7,17 @@
<title>Failmap - THE GAME</title>
{% leaflet_js plugins="forms" %}
{% leaflet_css plugins="forms" %}
<script type="text/javascript" src="{% static 'js/vendor/jquery-3.2.1.js' %}"></script>
<script type="text/javascript" src="{% static '/js/vendor/jquery-3.2.1.js' %}"></script>
<script type="text/javascript" src="{% static '/js/vendor/bootstrap.js' %}"></script>
<link rel="stylesheet" type="text/css" href="{% static 'css/vendor/leaflet.css' %}"/>
<link rel="stylesheet" type="text/css" href="{% static 'css/vendor/bootstrap.min.css' %}">
<link rel="stylesheet" type="text/css" href="{% static '/css/vendor/leaflet.css' %}"/>
<link rel="stylesheet" type="text/css" href="{% static '/css/vendor/bootstrap.min.css' %}">
<link rel="stylesheet" type="text/css" href="{% static '/css/overrides.css' %}">
{{ form.media }}
<style>
body {
padding-top: 70px;
}
.dropdown:hover .dropdown-menu {
display: block;
}
......@@ -80,19 +79,19 @@
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav mr-auto">
<li class="nav-item"><a class="nav-link" href="/game/scores/">Scores</a></li>
<li class="nav-item"><a class="nav-link" href="/game/map/">Map</a></li>
<li class="nav-item"><a class="nav-link" href="/game/contests/">Contests</a></li>
<li class="nav-item"><a class="nav-link" href="/game/scores/">🏆 Scores</a></li>
<li class="nav-item"><a class="nav-link" href="/game/map/">🗺️ Map</a></li>
<li class="nav-item"><a class="nav-link" href="/game/team/">Teams</a></li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="/game/submit_organization/" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Submit Organization <span class="caret"></span></a>
<a class="nav-link dropdown-toggle" href="/game/submit_organization/" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">➕ Organizations <span class="caret"></span></a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="/game/submit_organization/">Submit Organization</a>
<a class="dropdown-item" href="/game/submitted_organizations/">Known / Submitted Organizations</a>
</div>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="/game/submit_url/" id="navbarDropdown2" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Submit Url<span class="caret"></span></a>
<a class="nav-link dropdown-toggle" href="/game/submit_url/" id="navbarDropdown2" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">➕ Urls <span class="caret"></span></a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown2">
<a class="dropdown-item" href="/game/submit_url/">Submit Url</a>
<a class="dropdown-item" href="/game/submitted_urls/">Known / Submitted Urls</a>
......@@ -100,7 +99,7 @@
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="nav-item"><a class="nav-link" href="/game/rules_help/">? Help / FAQ</a></li>
<li class="nav-item"><a class="nav-link" href="/game/rules_help/">💡️ Help</a></li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown2" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Log on/off<span class="caret"></span></a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown3">
......
......@@ -6,7 +6,6 @@
<link rel="stylesheet" type="text/css" href="{% static '/css/vendor/leaflet.fullscreen.css' %}">
<link rel="stylesheet" type="text/css" href="{% static '/css/vendor/MarkerCluster.css' %}">
<link rel="stylesheet" type="text/css" href="{% static '/css/vendor/MarkerCluster.Failmap.css' %}">
<link rel="stylesheet" type="text/css" href="{% static '/css/overrides.css' %}">
<script type="text/javascript" src="{% url 'javascript-catalog' %}"></script>
<script type="text/javascript" src="{% static 'js/vendor/vue.js' %}"></script>
......
......@@ -17,9 +17,11 @@
<p style="width: 100%; text-align: center; font-size: 2em;">Starts <abbr title="{{ contest.from_moment }}">{{ contest.from_moment | naturaltime }}</abbr>. Deadline: <abbr title="{{ contest.until_moment }}">{{ contest.until_moment | naturaltime }}</abbr>.</p>
<div class="row">
{% for score in scores %}
<div class="col-md-4" style="margin-bottom: 30px;">
<table class="table table-sm table-striped table-bordered table-hover"
style="width: 29%; float:left; margin: 20px; box-shadow: 0px 13px 82px -47px rgba(0,0,0,0.75); background-color: {{ score.team_color_soft }}; {% if team.name == score.team %} border: 1px solid lightgreen; {% endif %}">
style="box-shadow: 0px 13px 82px -47px rgba(0,0,0,0.75); background-color: {{ score.team_color_soft }}; {% if team.name == score.team %} border: 1px solid lightgreen; {% endif %}">
<tbody>
<tr><td colspan="3"
style="font-weight: bold; font-family: impact, sans-serif; font-size: 6em; text-align: center;
......@@ -52,7 +54,9 @@
<tr><td>Low risk issues</td> <td>{{ score.low }}</td><td><small>* {{ score.low_multiplier }} = {{ score.low_score }}</small></td></tr>
</tbody>
</table>
</div>
{% endfor %}
</div>
<br style="clear: both">
......
......@@ -599,8 +599,10 @@ def contest_map_data(request):
updated_features = []
for feature in features:
# also check that there is something stored at all...
# not stored as geojsonfield anymore, because of implicit hate of that field.
if isinstance(feature['geometry']['coordinates'], str) and feature['geometry']['coordinates']:
feature['geometry']['coordinates'] = json.loads(feature['geometry']['coordinates'])
updated_features.append(feature)
else:
updated_features.append(feature)
......
......@@ -781,4 +781,9 @@ th.active .arrow {
.schedule_row {
font-size: 1.2em;
margin-bottom: 6px;
}
\ No newline at end of file
}
/* Menu hover menu is just a few pixels below the item. So it disappears if you're not moving too fast which is evil*/
.dropdown-menu {
top: 86% !important;
}
......@@ -7,34 +7,50 @@ const failmap = {
polygons: L.geoJson(), // geographical regions
// todo: if you click the group too fast: Marker.js:181 Uncaught TypeError:
// Cannot read property 'createIcon' of undefined
markers: L.markerClusterGroup({iconCreateFunction: function(cluster){
// getAllChildMarkers()
// if 1 is red, marker is red else if 1 is orange, else green else gray.
let css_class = "unknown";
// good, medium, bad
// todo: if red, break
// you can't break a forEach, therefore we're using an old school for loop here
let childmarkers = cluster.getAllChildMarkers();
let colors = ["unknown", "green", "yellow", "orange"];
let selected_color = 0;
for (let point of childmarkers) {
if (point.feature.properties.color === "red") {
css_class = "red"; break;
}
if (colors.indexOf(point.feature.properties.color) > selected_color){
selected_color = colors.indexOf(point.feature.properties.color);
css_class = point.feature.properties.color;
markers: L.markerClusterGroup(
// with this disabled, still get the createIcon error.
// It looks like the icons get eaten after showing them once. Can be replicated now.
// Even when there are no icons from our code, it crashes.
// It does not matter if the location of the marker is the same or differs (slightly)
// After the first or second expansion, the
// options.icon is undefined; can't access its "createIcon" property
// happens. The options/icon is eaten after the first expansionmarkerClusterGroup or something like that.
// icon is then null. And even if we don't make a marker, the same issue happens.
{
// zoomToBoundsOnClick: false,
// spiderfyOnMaxZoom: false,
iconCreateFunction: function(cluster){
// getAllChildMarkers()
// if 1 is red, marker is red else if 1 is orange, else green else gray.
let css_class = "unknown";
// good, medium, bad
// todo: if red, break
// you can't break a forEach, therefore we're using an old school for loop here
let childmarkers = cluster.getAllChildMarkers();
let colors = ["unknown", "green", "yellow", "orange"];
let selected_color = 0;
for (let point of childmarkers) {
if (point.feature.properties.color === "red") {
css_class = "red"; break;
}
if (colors.indexOf(point.feature.properties.color) > selected_color){
selected_color = colors.indexOf(point.feature.properties.color);
css_class = point.feature.properties.color;
}
}
}
return L.divIcon({
html: '<div><span>' + cluster.getChildCount() + '</span></div>',
className: 'marker-cluster marker-cluster-' + css_class,
iconSize: new L.Point(40, 40) });
}}),
return L.divIcon({
html: '<div><span>' + cluster.getChildCount() + '</span></div>',
className: 'marker-cluster marker-cluster-' + css_class,
// title: 'SWAG', // properties.organization_name
iconSize: [40, 40] }); // why a new L.Point? new L.Point(40, 40)
}}
),
greenIcon: new L.divIcon({className: 'leaflet-marker-green'}),
redIcon: new L.divIcon({className: 'leaflet-marker-red'}),
......@@ -117,8 +133,17 @@ const failmap = {
L.DomEvent
.disableClickPropagation(azoom)
.addListener(azoom, 'click', function() {
map.fitBounds(failmap.polygons.getBounds(),
{paddingTopLeft: [0,0], paddingBottomRight: [0, 0]})
// do not roll your own min() or max() over the bounds of these markers. It might wrap
// around.
let paddingToLeft = 0;
if (document.documentElement.clientWidth > 768)
paddingToLeft=320;
let bounds = failmap.polygons.getBounds();
bounds.extend(failmap.markers.getBounds());
map.fitBounds(bounds,
{paddingTopLeft: [0,0], paddingBottomRight: [paddingToLeft, 0]})
}, azoom);
return azoom;
};
......@@ -479,12 +504,12 @@ const failmap = {
pointToLayer: function (geoJsonPoint, latlng) {
// console.log(latlng);
switch (geoJsonPoint.properties.color){
case "red": return L.marker(latlng, {icon: failmap.redIcon});
case "orange": return L.marker(latlng, {icon: failmap.orangeIcon});
case "green": return L.marker(latlng, {icon: failmap.greenIcon});
case "yellow": return L.marker(latlng, {icon: failmap.yellowIcon});
case "red": return L.marker(latlng, {icon: failmap.redIcon, title: geoJsonPoint.properties.organization_name});
case "orange": return L.marker(latlng, {icon: failmap.orangeIcon, title: geoJsonPoint.properties.organization_name});
case "green": return L.marker(latlng, {icon: failmap.greenIcon, title: geoJsonPoint.properties.organization_name});
case "yellow": return L.marker(latlng, {icon: failmap.yellowIcon, title: geoJsonPoint.properties.organization_name});
}
return L.marker(latlng, {icon: failmap.grayIcon});
return L.marker(latlng, {icon: failmap.grayIcon, title: geoJsonPoint.properties.organization_name});
},
highlightFeature: function (e) {
......@@ -552,8 +577,8 @@ const failmap = {
plotdata: function (mapdata) {
// mapdata is a mix of polygons and multipolygons, and whatever other geojson types.
regions = []; // to polygons
points = []; // to markers
let regions = []; // to polygons
let points = []; // to markers
// the data is plotted on two separate layers which both have special properties.
// both layers have a different way of searching, clicking behaviour and so forth.
......@@ -585,8 +610,9 @@ const failmap = {
failmap.polygons.eachLayer(function (layer) {failmap.recolormap(mapdata.features, layer)});
// fit the map automatically, regardless of the initial positions
if (failmap.polygons.getLayers().length)
failmap.map.fitBounds(failmap.polygons.getBounds(), {paddingTopLeft: [0,0], paddingBottomRight: [paddingToLeft, 0]});
let bounds = failmap.polygons.getBounds();
bounds.extend(failmap.markers.getBounds());
failmap.map.fitBounds(bounds, {paddingTopLeft: [0,0], paddingBottomRight: [paddingToLeft, 0]});
} else {
// add regions
failmap.polygons = L.geoJson(regions, {
......@@ -599,8 +625,9 @@ const failmap = {
failmap.add_points(points);
// fit the map automatically, regardless of the initial positions
if (failmap.polygons.getLayers().length)
failmap.map.fitBounds(failmap.polygons.getBounds(), {paddingTopLeft: [0,0], paddingBottomRight: [paddingToLeft, 0]});
let bounds = failmap.polygons.getBounds();
bounds.extend(failmap.markers.getBounds());
failmap.map.fitBounds(bounds, {paddingTopLeft: [0,0], paddingBottomRight: [paddingToLeft, 0]});
}
},
......
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* Leaflet.markercluster 1.3.0+master.5b36e91,
* Leaflet.markercluster 1.4.1+master.37ab9a2,
* Provides Beautiful Animated Marker Clustering functionality for Leaflet, a JS library for interactive maps.
* https://github.com/Leaflet/Leaflet.markercluster
* (c) 2012-2017, Dave Leaver, smartrak
......@@ -428,6 +428,7 @@ var MarkerClusterGroup = L.MarkerClusterGroup = L.FeatureGroup.extend({
//If we aren't on the map (yet), blow away the markers we know of
if (!this._map) {
this._needsClustering = [];
this._needsRemoving = [];
delete this._gridClusters;
delete this._gridUnclustered;
}
......@@ -719,10 +720,11 @@ var MarkerClusterGroup = L.MarkerClusterGroup = L.FeatureGroup.extend({
},
_childMarkerDragEnd: function (e) {
if (e.target.__dragStart) {
this._moveChild(e.target, e.target.__dragStart, e.target._latlng);
}
var dragStart = e.target.__dragStart;
delete e.target.__dragStart;
if (dragStart) {
this._moveChild(e.target, dragStart, e.target._latlng);
}
},
......@@ -1411,7 +1413,7 @@ var MarkerCluster = L.MarkerCluster = L.Marker.extend({
},
//Recursively retrieve all child markers of this cluster
getAllChildMarkers: function (storageArray) {
getAllChildMarkers: function (storageArray, ignoreDraggedMarker) {
storageArray = storageArray || [];
for (var i = this._childClusters.length - 1; i >= 0; i--) {
......@@ -1419,6 +1421,9 @@ var MarkerCluster = L.MarkerCluster = L.Marker.extend({
}
for (var j = this._markers.length - 1; j >= 0; j--) {
if (ignoreDraggedMarker && this._markers[j].__dragStart) {
continue;
}
storageArray.push(this._markers[j]);
}
......@@ -1769,6 +1774,9 @@ var MarkerCluster = L.MarkerCluster = L.Marker.extend({
if (zoom < zoomLevelToStart || zoom < zoomLevelToStop) {
for (i = childClusters.length - 1; i >= 0; i--) {
c = childClusters[i];
if (c._boundsNeedUpdate) {
c._recalculateBounds();
}
if (boundsToApplyTo.intersects(c._bounds)) {
c._recursively(boundsToApplyTo, zoomLevelToStart, zoomLevelToStop, runAtEveryLevel, runAtBottomLevel);
}
......@@ -1787,24 +1795,21 @@ var MarkerCluster = L.MarkerCluster = L.Marker.extend({
* Extends L.Marker to include two extra methods: clusterHide and clusterShow.
*
* They work as setOpacity(0) and setOpacity(1) respectively, but
* they will remember the marker's opacity when hiding and showing it again.
* don't overwrite the options.opacity
*
*/
L.Marker.include({
clusterHide: function () {
this.options.opacityWhenUnclustered = this.options.opacity || 1;
return this.setOpacity(0);
var backup = this.options.opacity;
this.setOpacity(0);
this.options.opacity = backup;
return this;
},
clusterShow: function () {
var ret = this.setOpacity(this.options.opacity || this.options.opacityWhenUnclustered);
delete this.options.opacityWhenUnclustered;
return ret;
return this.setOpacity(this.options.opacity);
}
});
L.DistanceGrid = function (cellSize) {
......@@ -2112,7 +2117,7 @@ L.MarkerCluster.include({
return;
}
var childMarkers = this.getAllChildMarkers(),
var childMarkers = this.getAllChildMarkers(null, true),
group = this._group,
map = group._map,
center = map.latLngToLayerPoint(this._latlng),
......@@ -2190,7 +2195,7 @@ L.MarkerCluster.include({
var group = this._group,
map = group._map,
fg = group._featureGroup,
childMarkers = this.getAllChildMarkers(),
childMarkers = this.getAllChildMarkers(null, true),
m, i;
group._ignoreMove = true;
......@@ -2383,7 +2388,7 @@ L.MarkerCluster.include({
map = group._map,
fg = group._featureGroup,
thisLayerPos = zoomDetails ? map._latLngToNewLayerPoint(this._latlng, zoomDetails.zoom, zoomDetails.center) : map.latLngToLayerPoint(this._latlng),
childMarkers = this.getAllChildMarkers(),
childMarkers = this.getAllChildMarkers(null, true),
svg = L.Path.SVG,
m, i, leg, legPath, legLength, nonAnimatable;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment