Merge branch 'site-osm-baustelle' of https://github.com/hholzgra/maposmatic into site-osm-baustelle

pull/49/head
Hartmut Holzgraefe 2020-02-19 00:41:33 +01:00
commit 752eaad6ef
21 zmienionych plików z 492 dodań i 312 usunięć

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 552 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 625 KiB

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 90 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 109 KiB

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 52 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 88 KiB

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 8.9 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 15 KiB

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 52 KiB

Wyświetl plik

@ -38,15 +38,14 @@ Select a map area or upload a file
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
At the very beginning the map area to be rendered needs to be determined.
For this there are currently four alternatives, available as different
For this there are currently three alternatives, available as different
form tabs:
* Directly select a rectangular area on an online map
* Use a city or place name to look up its boundaries in the OSM database
* Upload a GPX track, the map area will be the tracks bounding box
* Upload an Umap file, the map area will be determined by the contained data
* Directly select a rectangular area on an online map.
* Use a city or place name to look up its boundaries in the OSM database.
* Upload a GPX track, Umap export, or GeoJSON file. The map area will be determined by the contained data.
When uploading a file you can still select a different, e.g. smaller or larger,
When uploading files you can still select a different, e.g. smaller or larger,
map area afterwards.
@ -94,47 +93,49 @@ which no border information is available in OSM yet, or the place area is too la
with this web service.
Upload a GPX Track
Upload data files
^^^^^^^^^^^^^^^^^^
image::select-gpx.png[GPX Upload,width=80%,pdfwidth=80%,align=center]
image::step-upload.png[File Upload,width=80%,pdfwidth=80%,align=center]
Here you can upload a GPX file containing GPS data and waypoints. The track, and all
named waypoints, will then be rendered on top of the base map.
Here you can upload data files containing geographic featuers in the form
of GPX tracks, http://umap.openstreetmap.fr[Umap] exports, or general
GeoJSON files, which will then be rendered on top of the base map.
For now you can only select a single GPX file, support for multiple track files may
be added in the future.
The upload form performs some basic checks, so it will complain when one of
the uploaded files is not in a supported format, or does not contain any
actual data.
The upload form performs some basic checks, so it will complain when the uploaded
file is not in GPX format, or does not contain any usable tracks.
Note that the file will be stored on the web server, and that the map generated from
it (but not the actual GPX file) will be visible to everyone. So do not upload any
sensitive data you don't want to to be seen in public, or that you don't have the
permission for to share it in public.
Note that the files will be stored on the web server, and that the map generated
from them (but not the actual uploaded files themselves) will be visible to
everyone. So do not upload any sensitive data you don't want to to be seen in
public, or that you don't have the permission to share in public.
Once files have been selected and verified, the form switches back to the
area selection tabl, where it will show a preview of the imported file
contents, and the optimal map area to display all contained data.
image::gpx-selected.png[GPX Preview,width=80%,pdfwidth=80%,align=center]
Once a valid GPX file has been selected the form switches back to the area selection
tab, and will show a preview of the file contents and the optimal map area to display
all contained GPS data.
If you want to render a different area, e.g. just a smaller part of the track, or a
larger area showing more context beyond the track area itself, you can change the
If you want to render a different area, e.g. just a smaller part of the data,
or a larger area showing more context beyond the data itself, you can change the
selection area accordingly.
Uploading a GPX track
+++++++++++++++++++++
When uploading a GPX track the contained track, and any named way points
will be rendered on top of the base map.
The actual final result of e.g. a rendered GPX track may look like the example below:
image::gpx-result.png[GPX Render Result,width=80%,pdfwidth=80%,align=center]
The actual final result of a rendered GPX track may look like the example to the left.
Uploading a Umap File
+++++++++++++++++++++
Upload a Umap File
^^^^^^^^^^^^^^^^^^
Here you can upload a file exported from Umap, a service that lets you create online
You can upload a file exported from Umap, a service that lets you create online
maps with your own markers and drawings on top. We provide you with a way to also use
this fine tool to produce customized printed maps with your own data on top, and not
only online maps.
@ -143,20 +144,12 @@ To create an export file from a Umap you created you need to click on the
“Embed and Share” Icon on the left side of the Umap interface, and then use
“Download Data → Full map data” in the sidebar on the right hand size.
The upload form performs some basic checks, so it will complain when the uploaded file
is not in Umap format, or does not contain any usable data.
Only data directly added using the Umap drawing tools will be rendered for now.
Umap also allows to import external data on the fly, like data form CSV files,
or dynamic queries against an Overpass API Server, this kind of data is not
supported by this service yet though, and so will not be part of the generated
print map.
Note that the file will be stored on the web server, and that the map generated from it
(but not the actual Umap file) will be visible to everyone. So do not upload any
sensitive data you don't want to to be seen in public, or that you don't have the
permission for to share it in public.
image::umap-selected.png[Umap Preview,width=80%,pdfwidth=80%,align=center]
Like with GPX uploads, once a valid Umap file has been selected for upload the form
@ -169,7 +162,7 @@ information, or actually want to show it in a larger map context.
image:umap-result.png[Umap Render Result,width=45%,pdfwidth=45%]
image:umap-actual.png[Umap Original Online Map,width=45%,pdfwidth=45%]
An actually rendered Umap map may look like the example on the left hand side,
An actually rendered Umap map may look like the example on the left hand side above,
while the right hand side shows how the original online Umap looks like.
The results are not completely the same , especially when it comes to line stroke
width, but this is mostly due to difference in size an resolution of the target
@ -184,16 +177,21 @@ In this step you can choose between different paper layouts.
image::step-layout.png[Paper Layout,width=80%,pdfwidth=80%,align=center]
There are three different single page layouts, and one for multi page
There are four different single page layouts, and one for multi page
booklets.
The basic single page layout uses the full page for the map.
The basic single page layout uses the full page for the map.
The other two single page layouts add a street index to the
The next two single page layouts add a street index to the
map, either on the side -- left side for left-to-write languages,
or right side for right-to-left languages like Arabic or Hebrew --
or at the bottom.
The fourth single page layout renders a full page map, like the
basic layout, and puts the street index on a second page in the
generated PDF. The other generated formats will not contain an
index as they do not support multi page output.
The multi page layout creates a multi page booklet with a title
page, an overview page, a collection of detail map pages, and
a street index.
@ -242,13 +240,23 @@ Select paper size an orientation
In this step the minimal required paper size is calculated,
and you are given a choice of predefined paper formats that
are larger than this, plus a "best fit" option.
are larger than this, plus a "best fit" option. You can select
one of the suggested paper sizes, or enter a custom width and
height that suits your needs yourself.
image::step-papersize.png[Paper size selection,width=80%,pdfwidth=80%,align=center]
You can also select the paper orientation here. The optimal
orientation is pre-selected automatically, but you can override
the default choice to fit your own needs.
For paper sizes large enough for the selected map area the
respective buttons are shown in blue, or in green for the
actual selected size. If a paper size is too small for the
given area the corresponding button is only shown in gray.
The left sie of the form will show a rough preview of the
chosen size and orientation, showing width and height and
a visual representation that will give you an idea of the
aspect ration. The preview also contains a rough scale
estimate, and the zoom factor the map will be redered with.
Select map title and locale
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -264,9 +272,9 @@ Also a quick summary of your choices is shown.
image::step-submit.png[Final steps,width=80%,pdfwidth=80%,align=center]
The map title is prefilled if you used the city selection
to specify the map area. If you uploaded a GPX or Umap
file the map title will also be prefilled if title information
was found in the uploaded file.
to specify the map area. If you uploaded GPX or Umap
files the map title will also be prefilled if title information
was found in the uploaded files.
The chosen locale is used for the annotations and copyright
information at the bottom of the map, and for section titles

Wyświetl plik

@ -37,6 +37,8 @@ from www.settings import RENDERING_RESULT_PATH, RENDERING_RESULT_MAX_SIZE_GB
import render
from django import db
_DEFAULT_POLL_FREQUENCY = 10 # Daemon job polling frequency, in seconds
_RESULT_MSGS = {
@ -119,6 +121,11 @@ class MapOSMaticDaemon:
"""
renderer = self.get_renderer(job, prefix)
job.start_rendering()
# make sure that existing DB connections are not re-used
# by the forked subprocess ...
db.connections.close_all()
ret = renderer.run()
job.end_rendering(_RESULT_MSGS[ret])
return ret == 0

Wyświetl plik

@ -479,17 +479,26 @@ class JobRenderer(threading.Thread):
LOG.warning("maybe PDF parsing is disabled in the ImageMagic Policy map? (e.g. /etc/ImageMagick-6/policy.xml)")
elif 'png' in RENDERING_RESULT_FORMATS:
try:
Image.MAX_IMAGE_PIXELS = None
img = Image.open(prefix + '.png')
img.save(prefix + '.jpg', quality=50)
try:
img = img.convert('RGB')
img.save(prefix + '.jpg', quality=50)
except Exception as e:
LOG.warning("PNG to JPEG conversion failed: %s" % e)
img.thumbnail((200, 200), Image.ANTIALIAS)
img.save(prefix + THUMBNAIL_SUFFIX)
try:
pngquant_cmd = [ "pngquant", "--output", "%s.8bit.png" % prefix,
"%s.png" % prefix ]
subprocess.check_call(pngquant_cmd)
except Exception as e:
LOG.warning("PNG color reduction failed: %s" % e)
except Exception as e:
LOG.warning("PNG size reduction failed: %s" % e)
img.close()
try:
pngquant_cmd = [ "pngquant", "--output", "%s.8bit.png" % prefix,
"%s.png" % prefix ]
subprocess.check_call(pngquant_cmd)
except Exception as e:
LOG.warning("PNG color reduction failed: %s" % e)
def run(self):
"""Renders the given job, encapsulating all processing errors and
@ -532,18 +541,24 @@ class JobRenderer(threading.Thread):
if self.job.overlay:
for overlay in self.job.overlay.split(","):
config.overlays.append(renderer.get_overlay_by_name(overlay))
if self.job.track:
config.gpx_file = os.path.join(MEDIA_ROOT, self.job.track.name)
else:
config.gpx_file = False
if self.job.umap:
config.umap_file = os.path.join(MEDIA_ROOT, self.job.umap.name)
else:
config.umap_file = False
if self.job.poi_file:
config.poi_file = os.path.join(MEDIA_ROOT, self.job.poi_file.name)
else:
config.poi_file = False
config.import_files = []
# legacy files, eventually remove these
config.gpx_file = False
config.umap_file = False
config.poi_file = False
for file in self.job.uploadfile_set.all():
config.import_files.append((file.file_type, os.path.join(MEDIA_ROOT, file.uploaded_file.name)))
# legacy files, eventually remove these
if file.file_type == 'gpx':
config.gpx_file = os.path.join(MEDIA_ROOT, file.uploaded_file.name)
if file.file_type == 'umap':
config.umap_file = os.path.join(MEDIA_ROOT, file.uploaded_file.name)
if file.file_type == 'poi':
config.poi_file = os.path.join(MEDIA_ROOT, file.uploaded_file.name)
config.paper_width_mm = self.job.paper_width_mm
config.paper_height_mm = self.job.paper_height_mm
except KeyboardInterrupt:

Wyświetl plik

@ -36,6 +36,8 @@ import ocitysmap
from www.maposmatic import models, widgets
import www.settings
from multiupload.fields import MultiFileField
class MapSearchForm(forms.Form):
"""
The map search form, allowing search through the rendered maps.
@ -57,7 +59,7 @@ class MapRenderingJobForm(forms.ModelForm):
'maptitle', 'administrative_city',
'lat_upper_left', 'lon_upper_left',
'lat_bottom_right', 'lon_bottom_right',
'track', 'umap', 'submittermail')
'submittermail')
mode = forms.CharField(initial='bbox', widget=forms.HiddenInput)
layout = forms.ChoiceField(choices=(), widget=forms.RadioSelect(attrs= { 'onchange' : 'clearPaperSize(); $("#layout-preview").attr("src","/media/img/layout/"+this.value+".png");'}))
@ -69,6 +71,7 @@ class MapRenderingJobForm(forms.ModelForm):
bbox = widgets.AreaField(label=_("Area"),
fields=(forms.FloatField(), forms.FloatField(),
forms.FloatField(), forms.FloatField()))
uploadfile = MultiFileField(required=False)
map_lang_flag_list = []
for lang_key, lang_name in www.settings.MAP_LANGUAGES_LIST:

Wyświetl plik

@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2020-02-15 11:20
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('maposmatic', '0016_submitterip_nullable'),
]
operations = [
migrations.CreateModel(
name='UploadFile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('uploaded_file', models.FileField(blank=True, null=True, upload_to='upload/general/%Y/%m/%d/')),
('file_type', models.CharField(choices=[('gpx', 'GPX Track'), ('umap', 'UMAP Export File'), ('poi', 'POI File')], max_length=4)),
('job', models.ManyToManyField(to='maposmatic.MapRenderingJob')),
],
),
migrations.RunSQL("""
INSERT INTO maposmatic_uploadfile (uploaded_file, file_type)
SELECT DISTINCT track AS uploaded_file, 'gpx' AS file_type
FROM maposmatic_maprenderingjob
WHERE track <> ''
""",
),
migrations.RunSQL("""
INSERT INTO maposmatic_uploadfile (uploaded_file, file_type)
SELECT DISTINCT umap AS uploaded_file, 'umap' AS file_type
FROM maposmatic_maprenderingjob
WHERE umap <> ''
""",
),
migrations.RunSQL("""
INSERT INTO maposmatic_uploadfile (uploaded_file, file_type)
SELECT DISTINCT poi_file AS uploaded_file, 'poi' AS file_type
FROM maposmatic_maprenderingjob
WHERE poi_file <> ''
""",
),
migrations.RunSQL("""
INSERT INTO maposmatic_uploadfile_job (uploadfile_id, maprenderingjob_id)
SELECT file.id AS uploadfile_id, job.id AS maprenderingjob_id
FROM maposmatic_uploadfile file
JOIN maposmatic_maprenderingjob job
ON job.track = file.uploaded_file
""",
),
migrations.RemoveField(
model_name='maprenderingjob',
name='poi_file',
),
migrations.RemoveField(
model_name='maprenderingjob',
name='track',
),
migrations.RemoveField(
model_name='maprenderingjob',
name='umap',
),
]

Wyświetl plik

@ -132,12 +132,6 @@ class MapRenderingJob(models.Model):
def __str__(self):
return self.maptitle.encode('utf-8')
track = models.FileField(upload_to='upload/tracks/%Y/%m/%d/', null=True, blank=True)
umap = models.FileField(upload_to='upload/umaps/%Y/%m/%d/', null=True, blank=True)
poi_file = models.FileField(upload_to='upload/poi/%Y/%m/%d/', null=True, blank=True)
def maptitle_computized(self):
t = self.maptitle.strip()
if self.id <= www.settings.LAST_OLD_ID:
@ -364,3 +358,15 @@ class MapRenderingJob(models.Model):
if errors:
raise ValidationError(errors)
class UploadFile(models.Model):
FILE_TYPES = (
('gpx', 'GPX Track'),
('umap', 'UMAP Export File'),
('poi', 'POI File')
);
uploaded_file = models.FileField(upload_to='upload/general/%Y/%m/%d/', null=True, blank=True)
file_type = models.CharField(max_length = 4, choices = FILE_TYPES)
job = models.ManyToManyField(MapRenderingJob)

Wyświetl plik

@ -159,16 +159,13 @@ $('#error-modal').modal('show')
<ul class="nav nav-tabs" id="locTabs">
<li class="nav-item">
<a class="nav-link active" id="step-location-bbox-tab" data-toggle="tab" href="#step-location-bbox" role="tab" aria-controls="home" aria-selected="true">{% trans "Geographic area" %}</a>
<a class="nav-link active" id="step-location-bbox-tab" data-toggle="tab" href="#step-location-bbox" role="tab" aria-controls="home" aria-selected="true"><i class="fas fa-globe-africa"></i> {% trans "Geographic area" %}</a>
</li>
<li class="nav-item">
<a class="nav-link" id="step-location-admin-tab" data-toggle="tab" href="#step-location-admin" role="tab" aria-controls="admin" aria-selected="false">{% trans "City search" %}</a>
<a class="nav-link" id="step-location-admin-tab" data-toggle="tab" href="#step-location-admin" role="tab" aria-controls="admin" aria-selected="false"><i class="fas fa-search-location"></i> {% trans "City search" %}</a>
</li>
<li class="nav-item">
<a class="nav-link" id="step-location-gpx-tab" data-toggle="tab" href="#step-location-gpx" role="tab" aria-controls="gpx" aria-selected="false">{% trans "GPX track" %}</a>
</li>
<li calss="nav-item">
<a class="nav-link" id="step-location-umap-tab" data-toggle="tab" href="#step-location-umap" role="tab" aria-controls="umap" aria-selected="false">{% trans "Umap data file" %}</a>
<a class="nav-link" id="step-location-gpx-tab" data-toggle="tab" href="#step-location-gpx" role="tab" aria-controls="gpx" aria-selected="false"><i class="fas fa-upload"></i> {% trans "File upload" %}</a>
</li>
</ul>
@ -194,52 +191,37 @@ $('#error-modal').modal('show')
<div class="tab-pane" id="step-location-gpx" role="tabpanel">
<div class="col-lg-12">
<br/>
<fieldset id="track-file">
<legend><i class="fas fa-file-upload"></i> {% trans "Upload files" %}</legend>
{{ form.uploadfile }}
<tt id="file-list">
</tt>
</fieldset>
<div style='height: 2ex'></div>
<div class="alert alert-secondary">
{% blocktrans trimmed %}
Upload a GPX file here. The GPX track stored in this file,
and any named waypoints, will be drawn on top of the created map.
Upload GPX, Umap, or general GeoJSON files here.
<br/>
You can select multiple files at once. If you re-open the
file selection dialog to select files, your selection will
replace the previous one.
{% endblocktrans %}
</div>
<div style='height: 2ex'></div>
<div class="alert alert-danger">
{% blocktrans trimmed %}
<b>Note:</b> The uploaded file will not be made available to anyone, the map created using this
<b>Note:</b> The uploaded files will not be made available to anyone, the map created using this
file <b>will be publicly visible</b> though.<br/>Do <b>NOT</b> upload any data you don't want to be publicly
visible.
{% endblocktrans %}
</div>
<fieldset id="track-file">
<legend>{% trans "GPX track file" %}</legend>
{{ form.track }}
</fieldset>
</div>
</div>
<div class="tab-pane" id="step-location-umap" role="tabpanel">
<div class="col-lg-12">
<br/>
<div class="alert alert-secondary">
{% trans "Upload an <a href='https://umap.openstreetmap.fr/'>Umap</a> file here." %}
<p>
{% blocktrans trimmed %}
Markers, lines and shapes that have been placed on that Umap will be
printed on top of the generated map.
{% endblocktrans %}
<p/>
</div>
<div class="alert alert-danger">
{% blocktrans trimmed %}
<b>Note:</b> The uploaded file will not be made available to anyone, the map created using this
file <b>will be publicly visible</b> though.<br/>Do <b>NOT</b> upload any data you don't want
to be publicly visible.
{% endblocktrans %}
</div>
<fieldset id="umap-file">
<legend>{% trans "Umap data file" %}</legend>
{{ form.umap }}
</fieldset>
</div>
</div>
</div>
<div class="alert alert-info">

Wyświetl plik

@ -0,0 +1,106 @@
{% load i18n %}
{% load extratags %}
{% include "./verify-gpx-file.js" %}
{% include "./verify-json-file.js" %}
var file_colors = ['red', 'blue', 'green', 'violet', 'orange'];
var upload_file_layers = [];
var upload_file_bounds = false;
function clear_upload_layers() {
var old_layer;
for (old_layer of upload_file_layers) {
old_layer.removeFrom(map);
}
upload_file_layers = [];
upload_file_bounds = false;
$("#file-list").text('');
}
function add_upload_layer(filename, new_layer) {
new_layer.addTo(map);
// txt += delim + files[i].name;
// delim = '; ';
upload_file_layers.push(new_layer);
var new_bbox = new_layer.getBounds();
if (upload_file_bounds == false) {
upload_file_bounds = new_bbox;
} else {
upload_file_bounds.extend(new_bbox);
}
map.fitBounds(upload_file_bounds);
if (upload_file_bounds.getSouthWest().equals(upload_file_bounds.getNorthEast())) {
upload_file_bounds = map.getBounds();
}
upload_file_bounds = upload_file_bounds.pad(0.1);
map.fitBounds(upload_file_bounds);
// TODO: fill file list display
// $("#file-list").text(txt);
$('#step-location-bbox-tab').tab('show'); // Select geo location tab
locationFilter.setBounds(upload_file_bounds);
locationFilter.enable();
}
function get_layer_titles() {
var layer, titles = [];
for (layer of upload_file_layers) {
if (layer.hasOwnProperty('maptitle')) {
titles.push(layer.maptitle);
}
}
return titles.join("; ");
}
$("#id_uploadfile").change(function() {
var upload_file;
clear_upload_layers();
var n = 0;
for (upload_file of $("#id_uploadfile")[0].files) {
var fr, file;
file = upload_file;
fr = new FileReader();
fr.filename = file.name;
fr.filenum = n;
n = n + 1;
fr.onload = function (e) {
if (e.target.result) {
layer = verify_upload_file(file.name, e.target.result, e.target.filenum);
if (layer != false) {
add_upload_layer(e.target.filename, layer);
}
} else {
alert("Could not read " + e.target.filename);
}
};
fr.readAsText(upload_file);
}
});
function verify_upload_file(filename, data_str, filenum) {
if (data_str.startsWith('<?xml')) {
return verify_gpx_data(data_str, filename, filenum);
} else if (data_str.startsWith('{')) {
return verify_json_data(data_str, filename, filenum);
}
alert(filename + ": unknown file type");
return false;
}

Wyświetl plik

@ -1,56 +0,0 @@
{% load i18n %}
{% load extratags %}
/* handle upload of GPX files*/
$("#id_track").change(function() {
loadFile($("#id_track")[0], function(xml) {
if (/Trident\/|MSIE/.test(window.navigator.userAgent)) {
// InterNet Explorer 10 / 11
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.loadXML(xml);
if (xmlDoc.parseError.errorCode!=0) {
alert("not a valid XML file");
$("#id_track")[0].value = '';
return false;
}
} else {
var parser = new DOMParser();
var parsererrorNS = parser.parseFromString('INVALID', 'text/xml').getElementsByTagName("parsererror")[0].namespaceURI;
var dom = parser.parseFromString(xml, 'text/xml');
if(dom.getElementsByTagNameNS(parsererrorNS, 'parsererror').length > 0) {
alert("not a valid XML file");
$("#id_track")[0].value = '';
return false;
}
}
var gpx = new L.GPX(xml, { async: false,
marker_options: {
wptIconUrls: false,
startIconUrl: false,
endIconUrl: false,
shadowUrl: false,
}
},
).addTo(map);
var new_bbox = gpx.getBounds();
if ('_northEast' in new_bbox === false) {
alert("Not a GPX file");
$("#id_track")[0].value = '';
return false;
}
$('#step-location-bbox').tab('show') // Select geo location tab
$('#id_maptitle').val(gpx.get_name());
new_bbox = new_bbox.pad(0.1)
map.fitBounds(new_bbox);
locationFilter.setBounds(new_bbox);
locationFilter.enable();
return true;
});
});

Wyświetl plik

@ -1,103 +0,0 @@
{% load i18n %}
{% load extratags %}
// TODO - this shouldn't be hardcoded, but read from the config file instead
var umap_style_mapping = {
"OpenStreetMap" : "CartoOsm",
"OSM-monochrome" : "CartoOsmBw",
"OSM Humanitarian (OSM-FR)": "Humanitarian",
"OSM-Fr" : "French",
"OSM hikebikemap" : "HikeBikeMap",
"OSM Deutschland (OSM-DE)" : "GermanCartoOSM",
"OSM OpenTopoMap" : "OpenTopoMap",
"OSM OpenRiverboatMap" : "OpenRiverboatMap",
"OSM Toner (Stamen)" : "Toner"
};
/* handle upload of UMAP files*/
$("#id_umap").change(function() {
loadFile($("#id_umap")[0], function(umap) {
var umap_json, layer, feature;
var new_features = []
try {
umap_json = JSON.parse(umap);
} catch(e) {
alert('This does not look like a valid GeoJson or Umap export file (json parse error)');
$("#id_umap")[0].value = '';
return false;
}
if (umap_json.type == 'umap') {
for (layer in umap_json.layers) {
for (feature in umap_json.layers[layer].features) {
new_features.push(umap_json.layers[layer].features[feature]);
}
}
var new_geojson = {'type': 'FeatureCollection', 'features': new_features};
var json_layer = L.geoJson(new_geojson).addTo(map);
var new_bbox = json_layer.getBounds();
if ('_northEast' in new_bbox === false) {
alert('Umap file contains no geometry data');
$("#id_umap")[0].value = '';
return false;
}
$('#step-location-bbox').tab('show') // Select geo location tab
$('#id_maptitle').val(umap_json.properties.name);
var umap_title;
try {
umap_title = umap_json.properties.tilelayer.name;
} catch (err) {
umap_title = "OSM-Fr";
}
if (umap_title in umap_style_mapping) {
$("input:radio[name=stylesheet][value='"+umap_style_mapping[umap_title]+"']").prop("checked",true);
}
map.fitBounds(new_bbox);
if (new_bbox.getSouthWest().equals(new_bbox.getNorthEast())) {
new_bbox = map.getBounds();
}
new_bbox = new_bbox.pad(0.1);
locationFilter.setBounds(new_bbox);
locationFilter.enable();
} else if (umap_json.type == 'FeatureCollection') {
var json_layer = L.geoJson(umap_json).addTo(map);
var new_bbox = json_layer.getBounds();
if ('_northEast' in new_bbox === false) {
alert('GeoJson file contains no geometry data');
$("#id_umap")[0].value = '';
return false;
}
$('#step-location-bbox').tab('show') // Select geo location tab
map.fitBounds(new_bbox);
if (new_bbox.getSouthWest().equals(new_bbox.getNorthEast())) {
new_bbox = map.getBounds();
}
new_bbox = new_bbox.pad(0.1);
locationFilter.setBounds(new_bbox);
locationFilter.enable();
return true;
} else {
alert('This does not look like a valid GeoJson or Umap export file (wrong or missing type info)');
$("#id_umap")[0].value = '';
return false;
}
return true;
});
});

Wyświetl plik

@ -0,0 +1,53 @@
{% load i18n %}
{% load extratags %}
function verify_gpx_data(data_str, filename, filenum)
{
if (/Trident\/|MSIE/.test(window.navigator.userAgent)) {
// InterNet Explorer 10 / 11
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.loadXML(data_str);
if (xmlDoc.parseError.errorCode!=0) {
alert("not a valid XML file");
return false;
}
} else {
var parser = new DOMParser();
var parsererrorNS = parser.parseFromString('INVALID', 'text/xml').getElementsByTagName("parsererror")[0].namespaceURI;
var dom = parser.parseFromString(data_str, 'text/xml');
if(dom.getElementsByTagNameNS(parsererrorNS, 'parsererror').length > 0) {
alert(filename + "is not a valid XML file");
return false;
}
}
var color = file_colors[filenum % file_colors.length];
var gpx_layer = new L.GPX(data_str, { async: false,
polyline_options: {
color: color,
opacity: 0.75,
},
marker_options: {
wptIconUrls: false,
startIconUrl: false,
endIconUrl: false,
shadowUrl: false,
}
},
);
var new_bbox = gpx_layer.getBounds();
if ('_northEast' in new_bbox === false) {
alert(filename + "is not a valid GPX file");
return false;
}
if (gpx_layer.get_name() != '') {
gpx_layer.maptitle = gpx_layer.get_name();
}
return gpx_layer;
}

Wyświetl plik

@ -0,0 +1,97 @@
{% load i18n %}
{% load extratags %}
function verify_json_data(data_str, filename, filenum)
{
var json_data;
try {
json_data = JSON.parse(data_str);
} catch(e) {
alert(filename + 'does not look like a valid GeoJson or Umap export file (json parse error)');
return false;
}
if (json_data.type == 'umap') {
return verify_umap_json_data(json_data, filename, filenum);
} else if (json_data.type == 'FeatureCollection') {
return verify_geojson_data(json_data, filename, filenum);
}
alert(filename + ' does not look like a valid GeoJson or Umap export file (wrong or missing type info)');
return false;
}
function verify_geojson_data(json_data, filename, filenum)
{
var color = file_colors[filenum % file_colors.length];
var json_layer = L.geoJson(json_data, {
style: function(feature) {
return { color: color };
}});
var new_bbox = json_layer.getBounds();
if ('_northEast' in new_bbox === false) {
alert(filename + ' does not seem to contain geometry data');
return false;
}
$('#step-location-bbox').tab('show') // Select geo location tab
return json_layer;
}
// TODO - this shouldn't be hardcoded, but read from the config file instead
var umap_style_mapping = {
"OpenStreetMap" : "CartoOsm",
"OSM-monochrome" : "CartoOsmBw",
"OSM Humanitarian (OSM-FR)": "Humanitarian",
"OSM-Fr" : "French",
"OSM hikebikemap" : "HikeBikeMap",
"OSM Deutschland (OSM-DE)" : "GermanCartoOSM",
"OSM OpenTopoMap" : "OpenTopoMap",
"OSM OpenRiverboatMap" : "OpenRiverboatMap",
"OSM Toner (Stamen)" : "Toner"
};
function verify_umap_json_data(json_data, filename, filenum)
{
var layer, feature, new_features = [];
for (layer in json_data.layers) {
for (feature in json_data.layers[layer].features) {
new_features.push(json_data.layers[layer].features[feature]);
}
}
var new_geojson = {'type': 'FeatureCollection', 'features': new_features};
var color = file_colors[filenum % file_colors.length];
var json_layer = L.geoJson(new_geojson, {
style: function(feature) {
return { color: color };
}});
var new_bbox = json_layer.getBounds();
if ('_northEast' in new_bbox === false) {
alert(filename + ' does not seem to contain geometry data');
return false;
}
$('#step-location-bbox').tab('show') // Select geo location tab
json_layer.maptitle = json_data.properties.name;
try {
var umap_style = json_data.properties.tilelayer.name;
if (umap_style in umap_style_mapping) {
// TODO: add a proper function for selecting the map style
$("input:radio[name=stylesheet][value='" + umap_style_mapping[umap_style] + "']").prop("checked", true);
}
} catch {
// ignore
}
return json_layer;
}

Wyświetl plik

@ -82,38 +82,7 @@ function setPrevNextLinks() {
{% include "./wizard-parts/wizardmap.js" %}
/* general file upload event handler */
function loadFile(input, onload_func) {
var file, fr;
if (typeof window.FileReader !== 'function') {
console.log("The file API isn't supported on this browser yet.");
return;
}
if (!input) {
console.log("Um, couldn't find the fileinput element.");
}
else if (!input.files) {
console.log("This browser doesn't seem to support the `files` property of file inputs.");
}
else if (!input.files[0]) {
console.log("Please select a file before clicking 'Load'");
}
else {
file = input.files[0];
fr = new FileReader();
fr.onload = receivedText;
fr.readAsText(file);
}
function receivedText() {
onload_func(fr.result);
}
}
{% include "./wizard-parts/upload-gpx-file.js" %}
{% include "./wizard-parts/upload-umap-file.js" %}
{% include "./wizard-parts/upload-files.js" %}
var currentTab = 0; // Current tab is set to be the first tab (0)
showTab(currentTab); // Display the current tab
@ -236,7 +205,10 @@ function country_lang(country_code)
function prepareLangTitle() {
// Prepare the language list
country_lang(country);
country_lang(country);
// Set title text
$('#id_maptitle').val(get_layer_titles());
// Seed the summary fields
if ($('#id_administrative_osmid').val()) {

Wyświetl plik

@ -28,6 +28,7 @@
import datetime
import logging
import json
import os
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.core.urlresolvers import reverse
@ -125,6 +126,18 @@ def donate_thanks(request):
"""The thanks for donation page."""
return render_to_response('maposmatic/donate-thanks.html')
def create_upload_file(job, file):
first_line = file.readline()
f = file.open()
LOG.info("firstline type %s" % type(first_line))
if first_line.startswith(b'<?xml'):
file_type = 'gpx'
else:
file_type = 'umap'
file_instance = models.UploadFile(uploaded_file = file, file_type = file_type)
file_instance.save()
file_instance.job.add(job)
def new(request):
"""The map creation page and form."""
@ -157,8 +170,13 @@ def new(request):
job.index_queue_at_submission = (models.MapRenderingJob.objects
.queue_size())
job.nonce = helpers.generate_nonce(models.MapRenderingJob.NONCE_SIZE)
job.save()
files = request.FILES.getlist('uploadfile')
for file in files:
create_upload_file(job, file)
return HttpResponseRedirect(reverse('map-by-id-and-nonce',
args=[job.id, job.nonce]))
else:
@ -306,12 +324,11 @@ def recreate(request):
.queue_size())
newjob.nonce = helpers.generate_nonce(models.MapRenderingJob.NONCE_SIZE)
newjob.track = job.track
newjob.umap = job.umap
newjob.poi_file = job.poi_file
newjob.save()
for each in job.uploadfile_set.all():
each.job.add(newjob)
return HttpResponseRedirect(reverse('map-by-id-and-nonce',
args=[newjob.id, newjob.nonce]))

Wyświetl plik

@ -32,7 +32,7 @@ from django.utils.translation import ugettext_lazy as _
from .settings_local import *
try:
from .settings_bounds import *
except:
except ModuleNotFoundError:
pass
from . import logconfig

Wyświetl plik

@ -4,6 +4,11 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@fortawesome/fontawesome-free": {
"version": "5.12.0",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.12.0.tgz",
"integrity": "sha512-vKDJUuE2GAdBERaQWmmtsciAMzjwNrROXA5KTGSZvayAsmuTGjam5z6QNqNPCwDfVljLWuov1nEC3mEQf/n6fQ=="
},
"@mapbox/leaflet-omnivore": {
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/@mapbox/leaflet-omnivore/-/leaflet-omnivore-0.3.4.tgz",