Move to use MariaDB's official Python client written in C instead of the PyMySQL library. This change doesn't rid Frappe of the PyMySQL library. Instead, it continues to utilize it for the ER module and converter methods until the MariaDB library adds support for the same. Ticket: https://jira.mariadb.org/projects/CONPY/issues/CONPY-203
100 lines
2.9 KiB
Python
100 lines
2.9 KiB
Python
# Copyright (c) 2020, Frappe Technologies and contributors
|
|
# License: MIT. See LICENSE
|
|
|
|
import frappe
|
|
|
|
|
|
@frappe.whitelist()
|
|
def get_coords(doctype, filters, type):
|
|
"""Get a geojson dict representing a doctype."""
|
|
filters_sql = get_coords_conditions(doctype, filters)[4:]
|
|
|
|
coords = None
|
|
if type == "location_field":
|
|
coords = return_location(doctype, filters_sql)
|
|
elif type == "coordinates":
|
|
coords = return_coordinates(doctype, filters_sql)
|
|
|
|
out = convert_to_geojson(type, coords)
|
|
return out
|
|
|
|
|
|
def convert_to_geojson(type, coords):
|
|
"""Converts GPS coordinates to geoJSON string."""
|
|
geojson = {"type": "FeatureCollection", "features": None}
|
|
|
|
if type == "location_field":
|
|
geojson["features"] = merge_location_features_in_one(coords)
|
|
elif type == "coordinates":
|
|
geojson["features"] = create_gps_markers(coords)
|
|
|
|
return geojson
|
|
|
|
|
|
def merge_location_features_in_one(coords):
|
|
"""Merging all features from location field."""
|
|
geojson_dict = []
|
|
for element in coords:
|
|
geojson_loc = frappe.parse_json(element["location"])
|
|
if not geojson_loc:
|
|
continue
|
|
for coord in geojson_loc["features"]:
|
|
coord["properties"]["name"] = element["name"]
|
|
geojson_dict.append(coord.copy())
|
|
|
|
return geojson_dict
|
|
|
|
|
|
def create_gps_markers(coords):
|
|
"""Build Marker based on latitude and longitude."""
|
|
geojson_dict = []
|
|
for i in coords:
|
|
node = {"type": "Feature", "properties": {}, "geometry": {"type": "Point", "coordinates": None}}
|
|
node["properties"]["name"] = i.name
|
|
node["geometry"]["coordinates"] = [i.latitude, i.longitude]
|
|
geojson_dict.append(node.copy())
|
|
|
|
return geojson_dict
|
|
|
|
|
|
def return_location(doctype, filters_sql):
|
|
"""Get name and location fields for Doctype."""
|
|
if filters_sql:
|
|
try:
|
|
coords = frappe.db.sql(
|
|
"""SELECT name, location FROM `tab{}` WHERE {}""".format(doctype, filters_sql), as_dict=True
|
|
)
|
|
except frappe.db.InternalError:
|
|
frappe.msgprint(frappe._("This Doctype does not contain location fields"), raise_exception=True)
|
|
return
|
|
else:
|
|
coords = frappe.get_all(doctype, fields=["name", "location"])
|
|
return coords
|
|
|
|
|
|
def return_coordinates(doctype, filters_sql):
|
|
"""Get name, latitude and longitude fields for Doctype."""
|
|
if filters_sql:
|
|
try:
|
|
coords = frappe.db.sql(
|
|
"""SELECT name, latitude, longitude FROM `tab{}` WHERE {}""".format(doctype, filters_sql),
|
|
as_dict=True,
|
|
)
|
|
except InternalError:
|
|
frappe.msgprint(
|
|
frappe._("This Doctype does not contain latitude and longitude fields"), raise_exception=True
|
|
)
|
|
return
|
|
else:
|
|
coords = frappe.get_all(doctype, fields=["name", "latitude", "longitude"])
|
|
return coords
|
|
|
|
|
|
def get_coords_conditions(doctype, filters=None):
|
|
"""Returns SQL conditions with user permissions and filters for event queries."""
|
|
from frappe.desk.reportview import get_filters_cond
|
|
|
|
if not frappe.has_permission(doctype):
|
|
frappe.throw(frappe._("Not Permitted"), frappe.PermissionError)
|
|
|
|
return get_filters_cond(doctype, filters, [], with_match_conditions=True)
|