def from_leaflet(lat1, lng1, lat2, lng2, cutoff, smoothing): if request.method != "POST": return "" json_i = request.get_json(force=True) if json_i is None: return "Could not parse JSON", 500 proj = ComplexLogProjection( LatLng(lat1, lng1), LatLng(lat2, lng2), math.radians(cutoff), smoothing_function_type=parse_smoothing(smoothing)) elements = json_i['data'] ret_v = [] for e in elements: x, y = tiling.from_leaflet_LatLng(LatLng(e['lat'], e['lng'])) xy = np.array([[x], [y]]) latlng_data = proj.invert(xy) assert latlng_data.shape == (2, 1) ret_element = {"lat": latlng_data[0, 0], "lng": latlng_data[1, 0]} ret_v.append(ret_element) response = app.response_class(response=json.dumps({"data": ret_v}), status=200, mimetype='application/json') return response
def test_single_loop(self): data = np.array([[0, 1, 0, 2], [1, 0, 3, 4]], dtype=float) projection = ComplexLogProjection(LatLng(0, 0), LatLng(10, 10), math.pi / 4) center = np.array([[5], [6]], dtype=float) projected = projection._single_forward(data.copy(), center, 1, 1) back = projection._single_backward(projected, center, 1, 1) np.testing.assert_almost_equal(back, data)
def test_loop(self): projection = ComplexLogProjection(LatLng(0, 0), LatLng(10, 10), math.pi / 4) # only small slice where no stitching was used data = np.array([[1, 9], [1, 9]]) res = projection(data.copy()) returned = projection.invert(res.copy()) np.testing.assert_almost_equal(returned, data) pass
def to_leaflet(lat1, lng1, lat2, lng2, cutoff, smoothing): if request.method != "POST": return "" json_i = request.get_json(force=True) if json_i is None: return "Could not parse JSON", 500 precision = int(request.args.get("precision", 5)) # number of digits c1latlng = LatLng(lat1, lng1) c2latlng = LatLng(lat2, lng2) proj = ComplexLogProjection( c1latlng, c2latlng, math.radians(cutoff), smoothing_function_type=parse_smoothing(smoothing)) center_distance = c1latlng.distanceTo(c2latlng) pixel_per_m = 256.0 / (156412.0) elements = json_i['data'] ret_v = [] for e in elements: xy = np.array([[e[0]], [e[0]]]) xy, clipping = proj(xy, calculate_clipping=True) z = proj.getZoomLevel(xy, pixel_per_m) latlng = tiling.to_leaflet_LatLng(xy[0, 0], xy[1, 0]) clipping = bool(clipping[0]) ret_element = [ round(latlng.lat, precision), round(latlng.lng, precision), round(z[0], precision), clipping ] ret_v.append(ret_element) z_values = list(map(lambda x: x[2], ret_v)) min_z = min(*z_values) max_z = max(*z_values) response = app.response_class(response=json.dumps( { "data": ret_v, "min_z": min_z, "max_z": max_z }, check_circular=False, indent=None), status=200, mimetype='application/json') return response
def do_projection(lat1, lng1, lat2, lng2, data_source: AbstractRasterDataProvider, pixel_width=256, pixel_height=256, xmin=-1, xmax=1, ymin=-1, ymax=1, cutoff=math.pi / 6, smoothing=CosCutoffSmoothingFunction, fileformat='png'): with t.time("setup"): trange = TargetSectionDescription(xmin, xmax, pixel_width, ymin, ymax, pixel_height) c1 = LatLng(lat1, lng1) c2 = LatLng(lat2, lng2) proj = ComplexLogProjection(c1, c2, cutoff, smoothing_function_type=smoothing) projector = RasterProjector(proj, data_source) with t.time("projection"): d = projector.project(trange) with t.time("parse_result"): pilim = Image.fromarray(d) with t.time("convert_to_format"): img_io = BytesIO() pilim.save(img_io, fileformat) img_io.seek(0) return send_file(img_io, mimetype='image/' + fileformat)
def test_project_image_distances(self): prov = get_providers() trange = TargetSectionDescription(-math.pi * 2, math.pi * 2, 4000, -math.pi, math.pi, 2000) #frankfurt_a_m = LatLng(50.115822, 8.702537) angle = 30 hamburg = LatLng(53.559988,9.982358) hamburg_elbbruecken = LatLng(53.535251,10.020135) lueneburg = LatLng(53.245280,10.408478) hannover = LatLng(52.370487,9.724743) fulda = LatLng(50.527068,9.684608) stockach = LatLng(47.847596,9.007671) for i,to in enumerate([ hamburg_elbbruecken,lueneburg,hannover,fulda,stockach]): projection = ComplexLogProjection(hamburg, to, math.radians(angle), smoothing_function_type=DualCosSmoothingFunction) projector_transparent = RasterProjector(projection, prov['transparent']) projector_mapbox = RasterProjector(projection, prov['mapbox']) d_trans = Image.fromarray(projector_transparent.project(trange)) d_mapbox = Image.fromarray(projector_mapbox.project(trange)) im = Image.alpha_composite(d_mapbox,d_trans) dist = int(hamburg.distanceTo(to)) filename = get_destination("sample-distance-" + str(dist)+".jpeg") im.convert('RGB').save(filename,optimize=True) print("Finished " + filename + " with distance " + str(dist))
def test_vis_zoomLevel(self): projection1 = ComplexLogProjection(LatLng(0, 0), LatLng(10, 10), math.pi / 4) projection2 = ComplexLogProjection(LatLng(-10, -10), LatLng(10, 10), math.pi / 4) projector = RasterProjector(projection1, OSMRasterDataProvider(dummy_resolver)) grid = projector.build_grid( TargetSectionDescription(-4, 4, 400, -2, 2, 200)) zoom = projection1.getZoomLevel(grid, 100) import matplotlib.pyplot as plt plt.imshow(zoom.reshape(200, 400)) plt.colorbar() plt.show() plt.scatter(range(400), zoom.reshape(200, 400)[10, :]) plt.show()
def test_project_dist_video(self): prov = get_providers() w = 2000 h = 1000 trange = TargetSectionDescription(-math.pi * 2, math.pi * 2, w, -math.pi,math.pi, h) # frankfurt_a_m = LatLng(50.115822, 8.702537) start = LatLng(48.783810, 9.180071) angle = 30 t = 5 fps = 25 end = LatLng(47.652839, 9.472735) # numsteps = 400 steps = list(reversed(list(map(lambda a:LatLng(a[0],a[1]),zip(np.linspace(end.lat,start.lat,numsteps,endpoint=False),np.linspace(end.lng,start.lng,numsteps,endpoint=False)))))) print("FPS:", fps) with tempfile.TemporaryDirectory() as tdir: files = [] for i,step in enumerate(steps): distance = start.distanceTo(step) projection = ComplexLogProjection(start, step, math.radians(angle), smoothing_function_type=DualCosSmoothingFunction) projector_transparent = RasterProjector(projection, prov['transparent']) projector_mapbox = RasterProjector(projection, prov['mapbox']) d_trans = Image.fromarray(projector_transparent.project(trange)) d_mapbox = Image.fromarray(projector_mapbox.project(trange)) im = Image.alpha_composite(d_mapbox, d_trans) filename = "sample-ch-distance-{:012.6f}.jpeg".format(distance) filepath = os.path.join(tdir, filename) files.append((filepath, distance)) im.convert('RGB').save(filepath, optimize=True) print(filepath) import cv2 out = cv2.VideoWriter(get_destination('distances.avi'), cv2.VideoWriter_fourcc(*'MJPG'), fps, (w, h)) for filepath, distance in files + list(reversed(files)): d = 0.01 im = cv2.imread(filepath) text = "{:05.2f}km".format(distance) fontscale = h / 200 linethickness = int(h / 100) cv2.putText(im, text, (int(w * d), int(h * (1 - d))), cv2.FONT_HERSHEY_SIMPLEX, fontscale, (255, 10, 1), linethickness, cv2.LINE_AA) out.write(im) out.release()
def project_image(self): projection = ComplexLogProjection(LatLng(0, 0), LatLng(10, 10), math.pi / 4) projector = RasterProjector(projection, CosSinRasterDataProvider()) trange = TargetSectionDescription(-1, 1, 500, -1, 1, 300) d = projector.project(trange) import matplotlib.pyplot as plt plt.imshow(d) plt.show()
def test_project_ch_video(self): prov = get_providers() w=2000 h = 1000 trange = TargetSectionDescription(-math.pi * 2, math.pi * 2, w, -math.pi, math.pi,h) #frankfurt_a_m = LatLng(50.115822, 8.702537) stuttgart = LatLng(48.783810,9.180071) num_steps = 200 fn = LatLng(47.652839, 9.472735) # angles = np.linspace(0,44.9,num_steps).tolist() fps = 25 print("FPS:",fps) with tempfile.TemporaryDirectory() as tdir: files = [] for angle in angles: projection = ComplexLogProjection(stuttgart, fn, math.radians(angle), smoothing_function_type=DualCosSmoothingFunction) projector_transparent = RasterProjector(projection, prov['transparent']) projector_mapbox = RasterProjector(projection, prov['mapbox']) d_trans = Image.fromarray(projector_transparent.project(trange)) d_mapbox = Image.fromarray(projector_mapbox.project(trange)) im = Image.alpha_composite(d_mapbox,d_trans) filename = "sample-ch-angle-{:05.2f}.jpeg".format(angle) filepath = os.path.join(tdir,filename) files.append((filepath,angle)) im.convert('RGB').save(filepath,optimize=True) print(filepath) import cv2 out = cv2.VideoWriter(get_destination('angles-{}.avi'.format('mapbox-osm')), cv2.VideoWriter_fourcc(*'MJPG'), fps, (w,h)) for filepath,angle in files + list(reversed(files)): d = 0.01 print("Loading ", filepath) im = cv2.imread(filepath) text = "{:05.2f}".format(angle) fontscale = h / 200 linethickness = int(h/100) cv2.putText(im, text, (int(w*d),int(h*(1-d))), cv2.FONT_HERSHEY_SIMPLEX, fontscale, (255,10,10), linethickness, cv2.LINE_AA) out.write(im) out.release()
def test_profile(self): projection = ComplexLogProjection( self.konstanz, self.hoffeld, math.pi / 6, smoothing_function_type=CosCutoffSmoothingFunction) projector = RasterProjector(projection, self.data_provider) trange = TargetSectionDescription(-math.pi * 2, math.pi * 2, 1600, -math.pi, math.pi, 200) d = projector.project(trange)
def test_profile_close(self): t2 = LatLng(47.656846, 9.179489) # sealive projection = ComplexLogProjection( self.konstanz, t2, math.pi / 6, smoothing_function_type=CosCutoffSmoothingFunction) projector = RasterProjector(projection, self.data_provider) trange = TargetSectionDescription(-math.pi * 2, math.pi * 2, 1600, -math.pi, math.pi, 200) d = projector.project(trange)
def test_complete(self): projection = ComplexLogProjection(LatLng(0, 0), LatLng(10, 10), math.pi / 4) data = np.array([[1, 45, 0, -45], [1, 0, 45, 45]]) reference = np.transpose( np.array([[-1.6044065604314688, -0.007577958547331141], [-1.6165580696347939, -2.061643517294472], [-1.6112081515800694, 2.0798741549084134], [-2.083894545839403, 1.5008744404655734]])) projected = projection(data) np.testing.assert_almost_equal(projected, reference) pass
def resolve(lat1, lng1, lat2, lng2, cutoff, smoothing, clickLat, clickLng): proj = ComplexLogProjection( LatLng(lat1, lng1), LatLng(lat2, lng2), math.radians(cutoff), smoothing_function_type=parse_smoothing(smoothing)) x, y = tiling.from_leaflet_LatLng(LatLng(clickLat, clickLng)) xy = np.array([[x], [y]]) latlng_data = proj.invert(xy) assert latlng_data.shape == (2, 1) ret_data = {"lat": latlng_data[0, 0], "lng": latlng_data[1, 0]} response = app.response_class(response=json.dumps(ret_data), status=200, mimetype='application/json') response.headers.add('Access-Control-Allow-Origin', '*') response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization') response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS') return response
def test_project_image_osm_small(self): konstanz = LatLng(47.711801, 9.084545) sealive = LatLng(47.656846, 9.179489) # sealive projection = ComplexLogProjection( konstanz, sealive, math.pi / 6, smoothing_function_type=CosCutoffSmoothingFunction) projector = RasterProjector(projection, OSMRasterDataProvider(dummy_resolver)) trange = TargetSectionDescription(-math.pi * 2, math.pi * 2, 500, -math.pi, math.pi, 250) d = projector.project(trange) import matplotlib.pyplot as plt plt.imshow(d) plt.show()
def test_project_image_osm(self): konstanz = LatLng(47.711801, 9.084545) hoffeld = LatLng(48.735051, 9.181156) projection = ComplexLogProjection( konstanz, hoffeld, math.pi / 6, smoothing_function_type=DualCosSmoothingFunction) projector = RasterProjector(projection, OSMRasterDataProvider(dummy_resolver)) trange = TargetSectionDescription(-math.pi * 2, math.pi * 2, 500, -math.pi, math.pi, 250) d = projector.project(trange) import matplotlib.pyplot as plt plt.imshow(d) plt.show()
def testZoomLevel(self): projection_small = ComplexLogProjection(LatLng(0, 0), LatLng(10, 10), math.pi / 4) projection_large = ComplexLogProjection(LatLng(-10, -10), LatLng(10, 10), math.pi / 4) data = np.array([[-1, -2, 1, 2], [1, 1, 1, 1]]) # expected = np.array([np.exp(1), np.exp(2), np.exp(1), np.exp(2)]) r1 = projection_small.getZoomLevel(data, 100) r2 = projection_large.getZoomLevel(data, 100) r3 = projection_small.getZoomLevel(data, 200) diff = r1 - r2 np.testing.assert_almost_equal(diff, np.array([1, 1, 1, 1])) assert r1[0] < r1[1] np.testing.assert_almost_equal(r3[0] - r1[0], 1) pass
def test_project_image_osm_wide(self): prov = get_providers() konstanz = LatLng(47.711801, 9.084545) leipzig = LatLng(51.348419, 12.370946) # projection = ComplexLogProjection( konstanz, leipzig, math.pi / 6, smoothing_function_type=CosCutoffSmoothingFunction) projector = RasterProjector(projection, prov['transparent']) trange = TargetSectionDescription(-math.pi * 4, math.pi * 4, 2000, -math.pi, math.pi, 500) d = projector.project(trange) import matplotlib.pyplot as plt plt.imshow(d) plt.savefig("sample.png", dpi=2000) plt.clf()
def test_project_ch(self): prov = get_providers() trange = TargetSectionDescription(-math.pi * 2, math.pi * 2, 4000, -math.pi, math.pi, 2000) #frankfurt_a_m = LatLng(50.115822, 8.702537) stuttgart = LatLng(48.783810,9.180071) fn = LatLng(47.652839, 9.472735) # for angle in [0,15,30,45]: projection = ComplexLogProjection(stuttgart, fn, math.radians(angle), smoothing_function_type=DualCosSmoothingFunction) projector_transparent = RasterProjector(projection, prov['ch']) projector_mapbox = RasterProjector(projection, prov['mapbox']) d_trans = Image.fromarray(projector_transparent.project(trange)) d_mapbox = Image.fromarray(projector_mapbox.project(trange)) im = Image.alpha_composite(d_mapbox,d_trans) filename = get_destination("sample-ch-angle-" + str(angle)+".jpeg") im.convert('RGB').save(filename,optimize=True) print(filename)
def test_project_image_angles(self): prov = get_providers() trange = TargetSectionDescription(-math.pi * 2, math.pi * 2, 4000, -math.pi/2, math.pi/2, 1000) #frankfurt_a_m = LatLng(50.115822, 8.702537) halle = LatLng(51.506136,11.964422) leipzig = LatLng(51.348419, 12.370946) # for angle in [0,15,30,45]: projection = ComplexLogProjection(halle, leipzig, math.radians(angle), smoothing_function_type=DualCosSmoothingFunction) projector_transparent = RasterProjector(projection, prov['transparent']) projector_mapbox = RasterProjector(projection, prov['mapbox']) d_trans = Image.fromarray(projector_transparent.project(trange)) d_mapbox = Image.fromarray(projector_mapbox.project(trange)) im = Image.alpha_composite(d_mapbox,d_trans) filename = get_destination("sample-angle-" + str(angle)+".jpeg") im.convert('RGB').save(filename,optimize=True) print(filename)
def test_distance_scaling(self): fs = (12,2.8) gridspec = {'width_ratios': [1,1,1,1,.15]} fig_distance,axes_distance = plt.subplots(1,5,num=0,figsize=fs,gridspec_kw=gridspec) fig_angle,axes_angle =plt.subplots(1,5,num=1,figsize=fs,gridspec_kw=gridspec) fig_area,axes_area = plt.subplots(1,5,num=2,figsize=fs,gridspec_kw=gridspec) fig_direction, axes_direction = plt.subplots(1,5,num=3,figsize=fs,gridspec_kw=gridspec) limb_length_max = 0.001 def apply_clipping(data:np.ndarray,clipping:np.ndarray): d = data.copy() d[clipping] = None return d res = 5000 for i,angle in enumerate([0,15,30,44.99]): projection = ComplexLogProjection(LatLng(-1,0),LatLng(1,0),math.radians(angle),smoothing_function_type=DualCosSmoothingFunction,preprojection=IdentityPreprojection()) trange = TargetSectionDescription(-2,2,res,-2,2,res) extent = [trange.xmin,trange.xmax,trange.ymin,trange.ymax] rp = RasterProjector(projection,CosSinRasterDataProvider) grid = rp.build_grid(trange) #offset = np.stack([ np.ones((grid.shape[1],))*0.01, np.ones((grid.shape[1],))*0],axis=0) offset = np.random.uniform(-limb_length_max/math.sqrt(2),limb_length_max/math.sqrt(2),grid.shape) offset_2 = np.stack([offset[1,:],-offset[0,:] ],axis=0) #offset_2 = np.random.uniform(-0.01,0.01,grid.shape) offset_up = np.stack([np.ones(grid.shape[1])*0,np.ones(grid.shape[1])*limb_length_max],axis=0) azimuthal_center_point = np.array([[0],[0]]) azimuthal_to_center_vec = azimuthal_center_point - grid azimuthal_to_center_vec_len = np.sqrt( np.sum(np.square(azimuthal_to_center_vec),axis=0,keepdims=True)) + 1e-7 grid_offset = grid+ offset grid_offset_2 = grid + offset_2 grid_up = grid + offset_up grid_towards_center = grid + limb_length_max * (azimuthal_to_center_vec/azimuthal_to_center_vec_len) euclid = euclideanDist(grid,grid_offset) grid_projected,clipping = projection(grid,calculate_clipping=True) grid_offset_projected = projection(grid_offset) grid_offset_projected_2 = projection(grid_offset_2) grid_up_projected = projection(grid_up) grid_towards_center_projected = projection(grid_towards_center) projected_euclid = euclideanDist(grid_projected,grid_offset_projected) ratio = projected_euclid / euclid ratio_e = np.expand_dims(ratio,axis=0) rsg = np.squeeze(rp.reshape_grid(ratio_e,trange,1),axis=-1) clipping = np.squeeze(rp.reshape_grid(np.expand_dims(clipping,axis=0),trange,1),axis=-1) minv,maxv = rsg.min(),rsg.max() ax = axes_distance.flat[i] ax.set_title("$\gamma = {}°$".format(angle)) im_distance = ax.imshow(apply_clipping(rsg,clipping) ,norm=LogNorm(0.1,10,clip=True) #,norm=LogNorm() ,extent=extent) delta1 = grid_offset- grid delta2 = grid_offset_2 - grid angles = anglesBetween(delta1,delta2) delta1_projected = grid_offset_projected - grid_projected delta2_projected = grid_offset_projected_2 - grid_projected angles_projected = anglesBetween(delta1_projected,delta2_projected) angle_diff = np.degrees( np.abs(angles-angles_projected)) angles_formatted = np.squeeze(rp.reshape_grid(angle_diff,trange,1),axis=-1) ax = axes_angle.flat[i] ax.set_title("$\gamma = {}°$".format(angle)) im_angle = ax.imshow(apply_clipping(angles_formatted,clipping), norm=Normalize(0,60,clip=True), extent=extent) area = triangleArea(grid,grid_offset,grid_offset_2) area_projected = triangleArea(grid_projected,grid_offset_projected,grid_offset_projected_2) area_ratio = np.squeeze(rp.reshape_grid(np.expand_dims(area_projected/area,axis=0),trange,1)) ax = axes_area.flat[i] ax.set_title("$\gamma = {}°$".format(angle)) im_area = ax.imshow(apply_clipping(area_ratio,clipping),norm=LogNorm(0.01,100),extent=extent) delta_to_center = grid_towards_center - grid delta_projected_up = grid_towards_center_projected - grid_projected d_angle = np.arctan2(delta_projected_up[1,:],delta_projected_up[0,:]) delta_angle = np.arctan2(delta_to_center[1,:],delta_to_center[0,:]) d_angle = np.abs(np.degrees(np.expand_dims(d_angle - delta_angle,axis=0)) ) da_data = np.squeeze(rp.reshape_grid(d_angle,trange,1)) ax = axes_direction.flat[i] ax.set_title("$\gamma = {}°$".format(angle)) im_direction = ax.imshow(apply_clipping(da_data,clipping),norm=Normalize(0,180),extent=extent) for axes in [axes_distance,axes_angle,axes_area,axes_direction]: for x in axes.flat[:4]: #x.grid(True,which='both',axis='both') x.set_aspect(1) #axes.flat[-1].set_aspect(8) h_pad = None w_pad = None pad = None tight_args = { "rect":[0,0,1,.9] } plt.figure(fig_distance.number) cbar = fig_distance.colorbar(im_distance,ax=axes_distance.tolist(),cax=axes_distance.flat[4],fraction=1.0) #cbar.set_clim(10 ** -1, 10 ** 1) cbar.set_label("Ratio of distance on original plane\nto distance on projected plane") fig_distance.suptitle("Distance ratio of transformed line segments with lengths of up to {}".format(limb_length_max)) fig_distance.tight_layout(**tight_args) plt.savefig('./distance.pdf') plt.figure(fig_angle.number) cbar = fig_angle.colorbar(im_angle,ax=axes_angle.ravel().tolist(),cax = axes_angle.flat[4]) #cbar.set_clim(10 ** -3, 180) cbar.set_label("Absolute angle deviation in °") fig_angle.suptitle("Angle difference for right angle triangles with leg lengths of up to {}".format(limb_length_max)) fig_angle.tight_layout(**tight_args) plt.savefig(get_destination('./angle.pdf')) plt.figure(fig_area.number) cbar = fig_area.colorbar(im_area,ax=axes_area.ravel().tolist(),cax = axes_area.flat[4]) cbar.set_clim(10 ** -2, 10 ** 3) cbar.set_label("Area ratio") fig_area.suptitle("Area ratio for right angle triangles with leg lengths up to {}".format(limb_length_max)) fig_area.tight_layout(**tight_args) plt.savefig(get_destination('./area.pdf')) plt.figure(fig_direction.number) cbar = fig_direction.colorbar(im_direction,ax=axes_direction.ravel().tolist(),cax = axes_direction.flat[4],ticks=[0,30,60,90,120,150,180]) cbar.set_clim(0, 180) cbar.set_label("Absolute angle deviation in °") fig_direction.suptitle("Direction change of an vector of length {} pointing towards the center point (0,0)".format(limb_length_max)) fig_direction.tight_layout(**tight_args) plt.savefig(get_destination('./direction.pdf'))
def test_single_example(self): projection = ComplexLogProjection(LatLng(0, 0), LatLng(10, 10), math.pi / 4) data = np.array([[1, 45, 0, -45], [1, 0, 45, 45]]) center = np.array([[0], [0]]) projection._single_forward(data, center, math.pi, 1)
def test_init(self): ComplexLogProjection(LatLng(0, 0), LatLng(10, 10), math.pi / 4)
def cities_projected(lat1, lng1, lat2, lng2, cutoff, smoothing): with t.time("loading_cities_lat_lng"): cities_lat_lng = np.array( list(map(lambda e: [e['lat'], e['lon']], get_cities()['elements']))).transpose() with t.time("parsing_params"): precision = int(request.args.get("precision", 5)) # number of digits c1latlng = LatLng(lat1, lng1) c2latlng = LatLng(lat2, lng2) proj = ComplexLogProjection( c1latlng, c2latlng, math.radians(cutoff), smoothing_function_type=parse_smoothing(smoothing)) center_distance = c1latlng.distanceTo(c2latlng) pixel_per_m = 256.0 / (156412.0) num_cities = cities_lat_lng.shape[1] with t.time("projection"): xy, clipping = proj(cities_lat_lng, calculate_clipping=True) with t.time("zoomlevel"): z = proj.getZoomLevel(xy, pixel_per_m) with t.time("tiling"): latlngs = [None] * num_cities for i in range(num_cities): latlng = tiling.to_leaflet_LatLng(xy[0, i], xy[1, i]) latlngs[i] = latlng with t.time("packaging"): ret_v = [None] * num_cities p_x_int = 10**precision p_x_float = 10.**precision my_round = lambda x: int(x * (p_x_int)) / (p_x_float) for i in range(num_cities): clipping_v = bool(clipping[i]) latlng = latlngs[i] ret_element = [ my_round(latlng.lat), my_round(latlng.lng), my_round(z[i]), clipping_v ] ret_v[i] = ret_element with t.time("assembly"): z_values = list(map(lambda x: x[2], ret_v)) min_z = min(*z_values) max_z = max(*z_values) response = app.response_class(response=json.dumps( { "data": ret_v, "min_z": min_z, "max_z": max_z }, check_circular=False, indent=None), status=200, mimetype='application/json') return response