initial
This commit is contained in:
commit
11f85b1975
21
.idea/YASARMapper.iml
Normal file
21
.idea/YASARMapper.iml
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="Flask">
|
||||
<option name="enabled" value="true" />
|
||||
</component>
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
<component name="TemplatesService">
|
||||
<option name="TEMPLATE_CONFIGURATION" value="Jinja2" />
|
||||
<option name="TEMPLATE_FOLDERS">
|
||||
<list>
|
||||
<option value="$MODULE_DIR$/../YASARMapper\templates" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
</module>
|
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
7
.idea/misc.xml
Normal file
7
.idea/misc.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.11 (YASARMapper)" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (YASARMapper)" project-jdk-type="Python SDK" />
|
||||
</project>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/YASARMapper.iml" filepath="$PROJECT_DIR$/.idea/YASARMapper.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
126
.idea/workspace.xml
Normal file
126
.idea/workspace.xml
Normal file
@ -0,0 +1,126 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="fab2b692-df07-4475-9920-89184af9570f" name="Changes" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/.idea/YASARMapper.iml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/inspectionProfiles/profiles_settings.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/modules.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/Dockerfile" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/app.py" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/templates/map.html" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="Flask Main" />
|
||||
<option value="HTML File" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="FlaskConsoleOptions" custom-start-script="import sys sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS]) from flask.cli import ScriptInfo locals().update(ScriptInfo(create_app=None).load_app().make_shell_context()) print("Python %s on %s\nApp: %s [%s]\nInstance: %s" % (sys.version, sys.platform, app.import_name, app.env, app.instance_path))">
|
||||
<envs>
|
||||
<env key="FLASK_APP" value="app" />
|
||||
</envs>
|
||||
<option name="myCustomStartScript" value="import sys sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS]) from flask.cli import ScriptInfo locals().update(ScriptInfo(create_app=None).load_app().make_shell_context()) print("Python %s on %s\nApp: %s [%s]\nInstance: %s" % (sys.version, sys.platform, app.import_name, app.env, app.instance_path))" />
|
||||
<option name="myEnvs">
|
||||
<map>
|
||||
<entry key="FLASK_APP" value="app" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="MarkdownSettingsMigration">
|
||||
<option name="stateVersion" value="1" />
|
||||
</component>
|
||||
<component name="ProjectColorInfo">{
|
||||
"associatedIndex": 6
|
||||
}</component>
|
||||
<component name="ProjectId" id="2apCCQY086bQUzCQRTZuOcw5dYT" />
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">{
|
||||
"keyToString": {
|
||||
"DefaultHtmlFileTemplate": "HTML File",
|
||||
"Flask server.YASARMapper.executor": "Run",
|
||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"git-widget-placeholder": "master",
|
||||
"ignore.virus.scanning.warn.message": "true",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"settings.editor.selected.configurable": "preferences.pluginManager",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}</component>
|
||||
<component name="RunManager">
|
||||
<configuration name="YASARMapper" type="Python.FlaskServer">
|
||||
<module name="YASARMapper" />
|
||||
<option name="target" value="$PROJECT_DIR$/app.py" />
|
||||
<option name="targetType" value="PATH" />
|
||||
<option name="ENV_FILES" value="" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="GOOGLE_API_KEY" value="AIzaSyB7eRVH82_8CjtTirgt8x1jeP4Bqvf5IOg" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="D:\yasarmapper\YASARMapper\.venv\Scripts\python.exe" />
|
||||
<option name="SDK_NAME" value="Python 3.11 (YASARMapper)" />
|
||||
<option name="WORKING_DIRECTORY" value="" />
|
||||
<option name="IS_MODULE_SDK" value="false" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||
<option name="launchJavascriptDebuger" value="false" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
<component name="SharedIndexes">
|
||||
<attachedChunks>
|
||||
<set>
|
||||
<option value="bundled-python-sdk-50da183f06c8-2887949eec09-com.jetbrains.pycharm.pro.sharedIndexes.bundled-PY-233.13135.95" />
|
||||
</set>
|
||||
</attachedChunks>
|
||||
</component>
|
||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="fab2b692-df07-4475-9920-89184af9570f" name="Changes" comment="" />
|
||||
<created>1705006008005</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1705006008005</updated>
|
||||
<workItem from="1705006014810" duration="6336000" />
|
||||
<workItem from="1705152473218" duration="109000" />
|
||||
<workItem from="1705152597513" duration="1277000" />
|
||||
<workItem from="1705428459903" duration="4231000" />
|
||||
<workItem from="1705482341049" duration="50000" />
|
||||
<workItem from="1705482409485" duration="7760000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
<component name="com.intellij.coverage.CoverageDataManagerImpl">
|
||||
<SUITE FILE_PATH="coverage/YASARMapper$YASARMapper.coverage" NAME="YASARMapper Coverage Results" MODIFIED="1705520887309" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="" />
|
||||
</component>
|
||||
</project>
|
17
Dockerfile
Normal file
17
Dockerfile
Normal file
@ -0,0 +1,17 @@
|
||||
# Use an official Python runtime as a parent image
|
||||
FROM python:3.8-slim-buster
|
||||
|
||||
# Set the working directory in the container to /app
|
||||
WORKDIR /app
|
||||
|
||||
# Add the current directory contents into the container at /app
|
||||
ADD . /app
|
||||
|
||||
# Install any needed packages specified in requirements.txt
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Make port 5000 available to the world outside this container
|
||||
EXPOSE 5000
|
||||
|
||||
# Run app.py when the container launches
|
||||
CMD ["python", "app.py"]
|
25
app.py
Normal file
25
app.py
Normal file
@ -0,0 +1,25 @@
|
||||
import os
|
||||
from flask import Flask, render_template, jsonify
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
@app.route('/api_key', methods=['GET'])
|
||||
def api_key():
|
||||
return jsonify({"apiKey": os.getenv("GOOGLE_API_KEY")})
|
||||
|
||||
|
||||
@app.route('/save_shape', methods=['POST'])
|
||||
def save_shape():
|
||||
shape_data = request.json
|
||||
# Process shape_data as needed
|
||||
return jsonify({"status": "success"})
|
||||
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def home():
|
||||
return render_template('map.html')
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run()
|
239
templates/map.html
Normal file
239
templates/map.html
Normal file
@ -0,0 +1,239 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet Fullscreen Map</title>
|
||||
<style>
|
||||
body, html {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#map {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
<script src="https://code.jquery.com/jquery-3.7.1.min.js"
|
||||
integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
|
||||
<script src="https://unpkg.com/osmtogeojson"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-geometryutil/0.9.0/leaflet.geometryutil.js"></script>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"/>
|
||||
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css"/>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script>
|
||||
<link rel="stylesheet" href="https://ppete2.github.io/Leaflet.PolylineMeasure/Leaflet.PolylineMeasure.css"/>
|
||||
<script src="https://ppete2.github.io/Leaflet.PolylineMeasure/Leaflet.PolylineMeasure.js"></script>
|
||||
<!-- Include the Leaflet Panel Layers plugin -->
|
||||
<link rel="stylesheet" href="https://opengeo.tech/maps/leaflet-panel-layers/dist/leaflet-panel-layers.src.css"/>
|
||||
<script src="https://opengeo.tech/maps/leaflet-panel-layers/dist/leaflet-panel-layers.src.js"></script>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.css"/>
|
||||
<script src="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<button id="select-linear-features">Linear Features</button>
|
||||
<div id="map"></div>
|
||||
<script>
|
||||
|
||||
|
||||
function addMeasurementLabel(layer, text) {
|
||||
var label = new L.Label();
|
||||
label.setContent(text);
|
||||
label.setLatLng(layer.getBounds().getCenter());
|
||||
map.showLabel(label);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////
|
||||
|
||||
|
||||
if (typeof osmtogeojson !== 'function') {
|
||||
console.error('osmtogeojson is not loaded properly');
|
||||
} else {
|
||||
console.log('osmtogeojson is loaded properly');
|
||||
}
|
||||
|
||||
var streets = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 19,
|
||||
attribution: '© <a href="http://openstreetmap.org">OpenStreetMap</a> contributors',
|
||||
});
|
||||
|
||||
var satellite = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
|
||||
maxZoom: 19,
|
||||
attribution: 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
|
||||
});
|
||||
|
||||
|
||||
var fintopo = L.tileLayer('https://wmts.mapant.fi/wmts_EPSG3857.php?z={z}&x={x}&y={y}', {
|
||||
maxZoom: 19,
|
||||
attribution: ''
|
||||
});
|
||||
|
||||
|
||||
var strava = L.tileLayer('https://proxy.nakarte.me/https/heatmap-external-a.strava.com/tiles-auth/all/purple/{z}/{x}/{y}.png?px=256', {
|
||||
maxZoom: 19,
|
||||
attribution: ''
|
||||
});
|
||||
|
||||
var map = L.map('map', {
|
||||
center: [61.49, 23.76],
|
||||
zoom: 13,
|
||||
layers: [streets] //default layer
|
||||
});
|
||||
|
||||
|
||||
// Define the base layers using the plugin's syntax
|
||||
var baseLayers = [
|
||||
{
|
||||
name: "OSM",
|
||||
layer: streets
|
||||
},
|
||||
{
|
||||
name: "ERSI Sattelite",
|
||||
layer: satellite
|
||||
},
|
||||
{
|
||||
name: "Suomi Topo",
|
||||
layer: fintopo
|
||||
}
|
||||
];
|
||||
|
||||
var overLayers = [
|
||||
{
|
||||
name: "Strava",
|
||||
layer: strava
|
||||
}
|
||||
];
|
||||
|
||||
// Add the panel layers control to the map
|
||||
var panelLayers = new L.Control.PanelLayers(baseLayers, overLayers, {
|
||||
collapsibleGroups: true,
|
||||
collapsed: true,
|
||||
position: 'topright'
|
||||
});
|
||||
map.addControl(panelLayers);
|
||||
|
||||
// Adding geocoder
|
||||
$.ajax({
|
||||
url: '/api_key',
|
||||
type: 'GET',
|
||||
success: function (response) {
|
||||
var geocoder = L.Control.geocoder({
|
||||
geocoder: L.Control.Geocoder.google({apiKey: response.apiKey}),
|
||||
position: 'topleft'
|
||||
}).addTo(map);
|
||||
}
|
||||
});
|
||||
|
||||
// Adding scale
|
||||
L.control.scale({metric: true, imperial: false}).addTo(map); //Adding scale
|
||||
// Initialize the FeatureGroup to store editable layers
|
||||
var drawnItems = new L.FeatureGroup();
|
||||
map.addLayer(drawnItems);
|
||||
|
||||
// Initialize the draw control and pass it the FeatureGroup of editable layers
|
||||
var drawControl = new L.Control.Draw({
|
||||
draw: {
|
||||
polyline: {
|
||||
metric: true, // Use metric measurements
|
||||
showLength: true // Show length of the polyline
|
||||
},
|
||||
polygon: {
|
||||
showArea: true, // Show area of the polygon
|
||||
metric: true
|
||||
},
|
||||
circle: {
|
||||
metric: true,
|
||||
showRadius: true // Show radius for circles
|
||||
},
|
||||
|
||||
rectangle: false,
|
||||
circlemarker: false
|
||||
},
|
||||
edit: {
|
||||
featureGroup: drawnItems
|
||||
}
|
||||
});
|
||||
|
||||
map.addControl(drawControl);
|
||||
|
||||
map.on(L.Draw.Event.CREATED, function (event) {
|
||||
var layer = event.layer;
|
||||
drawnItems.addLayer(layer);
|
||||
|
||||
var shape = layer.toGeoJSON();
|
||||
var shape_for_db = JSON.stringify(shape);
|
||||
|
||||
var measurementText;
|
||||
|
||||
if (event.layerType === 'polygon') {
|
||||
var area = L.GeometryUtil.geodesicArea(layer.getLatLngs()[0]);
|
||||
measurementText = "Area: " + area.toFixed(2) + " sqm";
|
||||
} else if (event.layerType === 'polyline') {
|
||||
var length = L.GeometryUtil.length(layer);
|
||||
measurementText = "Length: " + length.toFixed(2) + " m";
|
||||
} else if (event.layerType === 'circle') {
|
||||
var radius = layer.getRadius();
|
||||
var area = Math.PI * radius * radius;
|
||||
measurementText = "Area: " + area.toFixed(2) + " sqm";
|
||||
}
|
||||
|
||||
if (measurementText) {
|
||||
addMeasurementLabel(layer, measurementText);
|
||||
}
|
||||
|
||||
// Example AJAX call to send data to Flask
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/save_shape",
|
||||
data: shape_for_db,
|
||||
contentType: "application/json",
|
||||
dataType: "json",
|
||||
success: function (response) {
|
||||
console.log(response);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Adding polyline measure control
|
||||
L.control.polylineMeasure({
|
||||
position: 'topleft',
|
||||
unit: 'metres',
|
||||
showBearings: true,
|
||||
clearMeasurementsOnStop: false,
|
||||
showClearControl: true,
|
||||
showUnitControl: false
|
||||
}).addTo(map);
|
||||
|
||||
// Adding linear features
|
||||
document.getElementById('select-linear-features').addEventListener('click', function () {
|
||||
var overpassUrl = "https://overpass-api.de/api/interpreter";
|
||||
var query = `
|
||||
[out:json];
|
||||
(
|
||||
way["highway"](around:5000,61.49,23.76);
|
||||
way["waterway"](around:5000,61.49,23.76);
|
||||
);
|
||||
out body;
|
||||
>;
|
||||
out skel qt;
|
||||
`;
|
||||
|
||||
$.ajax({
|
||||
url: overpassUrl,
|
||||
type: 'GET',
|
||||
data: {
|
||||
data: query
|
||||
},
|
||||
success: function (response) {
|
||||
var geojson = osmtogeojson(response);
|
||||
L.geoJSON(geojson).addTo(map);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user