def osm_download(uid): """Function to download osm data. GET request: The osmdownload site is returned, which shows the bounding polygon for the selected layer and a form to choose the osm highway-types which should not be downloaded. POST request: The selected options in the request form and the bounding polygon coordinates are transformed to overpass query language. This data is used to call the osm_from_overpass function from the OSMDeviationfinder class, which will make an OverpassAPI query and dowload the returned osm data and yield the progress of the download back, which will be streamed to the client. """ uid = uid.encode("ISO-8859-1") if request.method == "POST": fdir = os.path.join(app.config["UPLOAD_FOLDER"], uid) f = os.path.join(fdir, str(uid) + ".osm") typesquery = "" for i in request.form: typesquery = typesquery + '["highway"!="' + i + '"]' dm = DevMap.query.filter_by(uid=uid).first() bbox = json.dumps(dm.boundsxy) bbox = bbox[bbox.find("[[") : bbox.find("]]") + 2].replace("[", "").replace("]", "").replace(",", "") devfinder = OSMDeviationfinder(connectioninfo) return Response(devfinder.osm_from_overpass(bbox, typesquery, f, uid), mimetype="text/html") return render_template("osmdownload.html", uid=uid)
def results(uid): """This function is used to show and handle the result generation options and process. GET request: Renders and returns a site showing result generation options. POST request: Gets the result generation options from the user and creates an object of the ResultOptions class which holds the user's chosen and default options. The create_results function from the OSMDeviationfinder class is called with the ResultOptions object as parameter. The create_results function uses 'yield' to return the progress, this is used to stream the progress to the client. """ uid = uid.encode("ISO-8859-1") if request.method == "POST": devfinder = OSMDeviationfinder(connectioninfo) devfinder.db_source = ogr.Open(devfinder.dbconnectioninfo_ogr, 1) result_options = ResultOptions(uid) dm = DevMap.query.filter_by(uid=uid).first() if ( current_user.is_authenticated() and dm.owner == current_user or dm.owner == User.query.filter_by(username="******").first() ): if "maxdevgrid" in request.form: result_options.maxdevgrid = True if "posdevlines" in request.form: result_options.posdevlines = True if "posdevlinedist" in request.form: result_options.posdevlinedist = request.form["posdevlinedist"] if "absdevgrid" in request.form: result_options.absdevgrid = True if "matchingrategrid" in request.form: result_options.matchingrategrid = True if "gridcellsize" in request.form: result_options.gridcellsize = request.form["gridcellsize"] if "unmatchedref" in request.form: result_options.unmatchedref = True if "unmatchedrefminlen" in request.form: result_options.unmatchedrefminlen = request.form["unmatchedrefminlen"] if "unmatchedosm" in request.form: result_options.unmatchedosm = True if "unmatchedosmminlen" in request.form: result_options.unmatchedosmminlen = request.form["unmatchedosmminlen"] if "matchedref" in request.form: result_options.matchedref = True if "matchedrefminlen" in request.form: result_options.matchedrefminlen = request.form["matchedrefminlen"] if "matchedosm" in request.form: result_options.matchedosm = True if "matchedosmminlen" in request.form: result_options.matchedosmminlen = request.form["matchedosmminlen"] if "minlevenshtein" in request.form: result_options.minlevenshtein = True if "minlev" in request.form: result_options.minlev = request.form["minlev"] if "maxlevenshtein" in request.form: result_options.maxlevenshtein = True if "maxlev" in request.form: result_options.maxlev = request.form["maxlev"] # Keep track of created results dm.posdevlines = result_options.posdevlines dm.maxdevgrid = result_options.maxdevgrid dm.absdevgrid = result_options.absdevgrid dm.matchingrategrid = result_options.matchingrategrid dm.gridcellsize = result_options.gridcellsize dm.unmatchedref = result_options.unmatchedref dm.unmatchedosm = result_options.unmatchedosm dm.matchedref = result_options.matchedref dm.matchedosm = result_options.matchedosm dm.minlevenshtein = result_options.minlevenshtein dm.maxlevenshtein = result_options.maxlevenshtein db.session.add(dm) db.session.commit() return Response(devfinder.create_results(result_options), mimetype="text/html") else: return render_template("results.html", uid=uid)
def linematch(uid): """This function is used to show and handle the linematching options and process. GET request: Renders and returns a site showing linematching options. POST request: Gets the linematching options from the user and creates an object of the LinematchOptions class which holds the user's chosen and default options. The linematch_datasets function from the OSMDeviationfinder class is called with the LinematchOptions object as parameter. The linematch_datasets function uses 'yield' to return the progress, this is used to stream the progress to the client. """ uid = uid.encode("ISO-8859-1") dm = DevMap.query.filter_by(uid=uid).first() if request.method == "POST": devfinder = OSMDeviationfinder(connectioninfo) devfinder.db_source = ogr.Open(devfinder.dbconnectioninfo_ogr, 1) linematch_options = LinematchOptions(uid) linematch_options.keepcolumns_t2 = {"osm_id": "varchar"} if "searchradius" in request.form: linematch_options.searchradius = request.form["searchradius"] if "maxpotentialmatches" in request.form: linematch_options.maxpotentialmatches = request.form["maxpotentialmatches"] if "minmatchingfeatlen" in request.form: linematch_options.minmatchingfeatlen = request.form["minmatchingfeatlen"] if "maxlengthdiffratio" in request.form: linematch_options.maxlengthdiffratio = request.form["maxlengthdiffratio"] if "maxanglediff" in request.form: linematch_options.maxanglediff = request.form["maxanglediff"] if "posdiffsegmentlength" in request.form: linematch_options.posdiffsegmentlength = request.form["posdiffsegmentlength"] if "hausdorffsegmentlength" in request.form: linematch_options.hausdorffsegmentlength = request.form["hausdorffsegmentlength"] if "maxazimuthdiff" in request.form: linematch_options.maxazimuthdiff = request.form["maxazimuthdiff"] if "maxmeanposdifftolengthratio" in request.form: linematch_options.maxmeanposdifftolength = request.form["maxmeanposdifftolengthratio"] if "minmeanposdifftolengthratio" in request.form: linematch_options.minmeanposdifftolength = request.form["minmeanposdifftolengthratio"] if "exportdevvec" in request.form: linematch_options.deviationvectorlayer = True else: linematch_options.deviationvectorlayer = False dm.searchradius2 = linematch_options.searchradius dm.minmatchingfeatlen = linematch_options.minmatchingfeatlen dm.maxlengthdiffratio = linematch_options.maxlengthdiffratio dm.maxanglediff = linematch_options.maxanglediff dm.maxpotentialmatches = linematch_options.maxpotentialmatches dm.posdiffsegmentlength = linematch_options.posdiffsegmentlength dm.hausdorffsegmentlength = linematch_options.hausdorffsegmentlength dm.maxazimuthdiff = linematch_options.maxazimuthdiff dm.maxmeanposdevtolength = linematch_options.maxmeanposdevtolength dm.minmeanposdevtolength = linematch_options.minmeanposdevtolength dm.maxabsolutmeanposdev = linematch_options.maxabsolutmeanposdev dm.maxdeviation = linematch_options.maxdeviation db.session.add(dm) db.session.commit() return Response(devfinder.linematch_datasets(linematch_options), mimetype="text/html") return render_template("linematch.html", uid=uid, dm=dm)
def harmonize(uid): """This function is used to show and handle the harmonization options and process. GET request: Renders and returns a site showing harmonization options. POST request: Gets the harmonization options from the user and creates an object of the HarmonizeOptions class which holds the user's chosen and default options. The harmonize_datasets function from the OSMDeviationfinder class is called with the HarmonizeOptions object as parameter. The harmonize_datasets function uses 'yield' to return the progress, this is used to stream the progress to the client. """ uid = uid.encode("ISO-8859-1") devfinder = OSMDeviationfinder(connectioninfo) dm = DevMap.query.filter_by(uid=uid).first() if request.method == "POST": devfinder.db_source = ogr.Open(devfinder.dbconnectioninfo_ogr, 1) harmonization_options = HarmonizeOptions(uid) #: Keep column osm_id while processing harmonization_options.keepcolumns_t2 = {"osm_id": "varchar"} if "azimuthdifftolerance" in request.form: harmonization_options.azimuthdifftolerance = request.form["azimuthdifftolerance"] if "maxcheckpointanglediff" in request.form: harmonization_options.maxcheckpointanglediff = request.form["maxcheckpointanglediff"] if "searchradius" in request.form: harmonization_options.searchradius = request.form["searchradius"] if "presplitref" in request.form: harmonization_options.presplitref = True if "presplitosm" in request.form: harmonization_options.presplitosm = True if "harmonize" in request.form: harmonization_options.harmonize = True if "cleanref" in request.form: harmonization_options.cleanref = True if "cleanosm" in request.form: harmonization_options.cleanosm = True if "cleandistance" in request.form: harmonization_options.cleanosmradius = request.form["cleandistance"] harmonization_options.cleanrefradius = request.form["cleandistance"] if "streetnamecol" in request.form: harmonization_options.streetnamecol = request.form["streetnamecol"] if harmonization_options.streetnamecol == "NoNameCol": devfinder.create_nonamecolumn("odf_" + uid + "_ref") dm.basetable = harmonization_options.basetable dm.harmonize = harmonization_options.harmonize dm.reftable = harmonization_options.reftable dm.osmtable = harmonization_options.osmtable dm.streetnamecol = harmonization_options.streetnamecol dm.outsuffix = harmonization_options.outsuffix dm.keepcolumns_t1 = harmonization_options.keepcolumns_t1 dm.keepcolumns_t2 = harmonization_options.keepcolumns_t2 dm.cleanref = harmonization_options.cleanref dm.cleanosm = harmonization_options.cleanosm dm.cleanrefradius = harmonization_options.cleanrefradius dm.cleanosmradius = harmonization_options.cleanosmradius dm.presplitref = harmonization_options.presplitref dm.presplitosm = harmonization_options.presplitosm dm.searchradius = harmonization_options.searchradius dm.azimuthdifftolerance = harmonization_options.azimuthdifftolerance dm.maxcheckpointanglediff = harmonization_options.maxcheckpointanglediff dm.max_roads_countdiff = harmonization_options.max_roads_countdiff dm.max_azdiff = harmonization_options.max_azdiff dm.max_distancediff = harmonization_options.max_distancediff db.session.add(dm) db.session.commit() return Response(devfinder.harmonize_datasets(harmonization_options), mimetype="text/html") namecolumns = devfinder.get_textcolumns("odf_" + uid + "_ref") return render_template("harmonize.html", uid=uid, namecolumns=namecolumns, dm=dm)
def import_to_db(uid): """Function to import features from a layer of a shapefile into the database and calculation of the concavehull of the features in the table to use as a bounding polygon for the OverpassAPI request. GET request: The import site is returned, containing a set of the uploaded shapefiles. The user can then choose the shapefile to import. POST request: The chosen layer will be imported into a new table using the the function layer_to_db from the OSMDeviationfinder class. This function will import the features and convert multigeometry features to single geometry features. After a successful import, the concavehull of the imported data is generated using the function get_concavehull of the OSMDeviationfinder class. The concavhull is saved for the current devmap in the xy (for the OverpassAPI) and yx (for leaflet.js) representation. After that, the osm data download site is returned. """ error = None fdir = os.path.join(app.config["UPLOAD_FOLDER"], uid) fdata = dict() if request.method == "POST": uid = uid.encode("ISO-8859-1") fdata["datasource"] = request.form["source"] fdata["title"] = request.form["title"] fdata["datalicense"] = request.form["license"] fdata["shapefile"] = request.form["shapefile"] fdata["wmsformat"] = request.form["wmsformat"] fdata["wmsurl"] = request.form["wmsurl"] fdata["wmslayer"] = request.form["wmslayer"] if len(fdata["datasource"]) < 4: error = "Please define a data source with at least 4 characters." if len(fdata["datalicense"]) < 3: error = "Please a license with at least 2 characters." if len(fdata["title"]) < 4: error = "Please define a title with at least 4 characters." if len(fdata["wmsurl"]) > 1 or len(fdata["wmslayer"]) > 1 or len(fdata["wmsformat"]) > 1: if not (fdata["wmsurl"]) > 12 and len(fdata["wmslayer"]) > 3 and len(fdata["wmsformat"]) > 12: error = "All fields for a custom WMS Basemap have to be filled." if not "image" in fdata["wmsformat"]: error = "Please define a correct image format eg. image/jpeg" else: dm = DevMap.query.filter_by(title=fdata["title"]).first() if dm and dm.uid != uid: error = 'The title "' + fdata["title"] + '" is already chosen. Please try another title.' if fdata["shapefile"] == "No Shapefile found!": error = "No shapefile was found." if error is None: f = os.path.join(fdir, fdata["shapefile"]) tablename = "odf_" + uid + "_ref" shapefile = ogr.Open(f) devfinder = OSMDeviationfinder(connectioninfo) s = shapefile.GetLayerByIndex(0) devfinder.layer_to_db(s, tablename, True) concavehull = devfinder.get_concavehull(tablename) dm = DevMap.query.filter_by(uid=uid).first() if ( current_user.is_authenticated() and dm.owner == current_user or dm.owner == User.query.filter_by(username="******").first() ): boundsyx = { "type": "Feature", "properties": { "uid": uid, "title": fdata["title"], "author": dm.owner.username, "source": fdata["datasource"], }, "geometry": {"type": "Polygon", "coordinates": [concavehull[1]["coordinates"][0]]}, } boundsxy = { "type": "Feature", "properties": { "uid": uid, "title": fdata["title"], "author": dm.owner.username, "source": fdata["datasource"], }, "geometry": {"type": "Polygon", "coordinates": [concavehull[0]["coordinates"][0]]}, } dm.boundsxy = boundsxy dm.boundsyx = boundsyx dm.datasource = fdata["datasource"] dm.title = fdata["title"] dm.datalicense = fdata["datalicense"] dm.basemapwmsurl = fdata["wmsurl"] dm.basemapwmslayer = fdata["wmslayer"] dm.basemapwmsformat = fdata["wmsformat"] db.session.add(dm) db.session.commit() return redirect(url_for("devmap.osm_download", uid=uid)) shapefiles = [] for f in os.listdir(fdir): if f.endswith(".shp") and not f.startswith("."): s = Shapefile(f, None, fdir) shapefiles.append(s) return render_template("import.html", shapefiles=shapefiles, uid=uid, error=error, fdata=fdata)