Given a surface area, longitude and latitude, is there a formula for determining the best resolution to use with Google Tiles to map the area? - python

I'm trying to create a series of maps showing general geographic features (e.g. major roads and town names) using Cartopy and Matplotlib, but have been stumped trying to write a function to calculate the right resolution when adding the Google Tiles.
I've tried looking into how the resolution and tiles work but it's all getting a bit confusing. I was able to compute the meters per pixel given the latitude and resolution but nothing that connects to the square area that I'm shown, so I'm wondering if there is an easier way to estimate the best resolution to plot a rectangular area given:
latitude and longitude of the centroid
surface area of the rectangular area (in sq km)
Specifically, I want to be able to choose a resolution that looks best and shows the general landscape given the surface area being mapped and its geocoordinates.

Related

Plot a vector field over earth coordinate map using python

End goal:
Plot of the vector field of earth's magnetic field over a part of a city map using python
Prerequisites:
I have taken measurements of earth's magnetic field at multiple points in the area that I want to display in the end, but not using a regular grid for the points because of obstructing objects using the RWTH PhyPhox-App for iOS. At each location I have around 2k measurements of the three axis of the magnetometer as well as some (like 20 or so) measurements of the location using GPS. I always aligned the y axis of the phone (the one pointing from the speakers to the top) with the sun as a way to know the compass direction without relying on an actual compass (as that would defeat the purpose of cartographing the magnetic field).
What I have so far:
I wrote code that extracts the time, the location as well as of course the magnetic field measurements from the various .csv-files I get from the app and averages over the 2k measurements in each dimension to get a value for the magnetic field vector at that specific spot.
Next I calculate the azimuth angle of the sun at that location in order to be able to do a coordinate transformation that transforms from the phone coordinate system to an earth coordinate system.
So now I have datapoints with location, and a vector of the magnetic field at that point in an earth-fixed coordinate system.
What I need now:
Now I need a way to display these vectors as a vector field on top of a map of the part of my city the measurements were taken in. I read about the python implementation of plotly as well as geopandas but I did not find a way to plot vector fields, only scatter plots and "temperature"-plots (i.e. I could plot the strength of the vector field but not the direction).
Can anyone point me in the right direction on how to accomplish this?

Circle coordinates to cover larger circle in python

I am using Google Places API to find all cafes in a single area. Since the API maxes out at 60 results, I would need to apply some sort of grid search to cover the entire desired area.
I am looking for a python code where I could insert the objective coordinate (center of NY), desired large radius (5km), and small radius (0.5km). The algorithm would try identify the center coordinates of the smaller circles to cover the larger one completely. Output of the code would be list of coordinates of the smaller circles.
It doesn’t matter if the circles overlap each other or overflow the outer boundaries. This site had good visualizations of how the smaller circles could fill out the larger one https://math.stackexchange.com/questions/898247/the-minimum-number-of-circles-in-order-to-obtain-a-cover-of-a-specific-square

How to have Shapely polygon understand Earth projection?

I am interested in having my Shapely polygon understand the crossover from a longitude of 179 degrees to -179 degrees. As can be seen with the plot below, this Polygon is understandably viewed as spanning from -179 to +179. Is there anyway around this (to get it to view it as spanning from +179 to -179 and thus having an area of 2? Thank you!
import geopandas
from shapely.geometry import Polygon
p = Polygon([[179,5],[179,6],[-179,6],[-179,5],[179,5]])
p_gs = geopandas.GeoSeries(p,crs= "EPSG:4326")
p_gs.plot()
I see what you mean.
But a map is not a globe.
(After opening the OSM map in QGIS, etc., keep moving to the right. There is only a blank space.)
epsg 4326 i.e. the longitude and latitude coordinate system ends at 180 on both sides. It represents only 180 from the reference point.
Therefore, to do the work you want, you need to select a coordinate system that can represent the part and then draw again.
Choose a coordinate system that allows for meter-based calculations(area or Euclidean distances must use the TM coordinate system) and the reference point represents the desired area.
After that, it seems to be necessary to draw a picture by changing the longitude and latitude to the coordinates that fit the CRS.

How to consistently number contours in an image time series?

I have automated the task of measuring plant area over time to extrapolate growth rate using an image time-series and the following two methods: (1) Python + ArcGIS, and (2) Python + OpenCV.
In the first method, ArcGIS allows me to create a vector grid on the image. Each cell of the grid contains a single plant, so I number each cell starting from top-left to bottom-right. After creating a binary image in which plant pixels == 1 and everything else == 0, I apply Zonal Statistics to find my plant area. In this way the plant numbers stay consistent because I use the same grid over all the images in the time series, but it requires manual intervention.
In the second method, I use OpenCV to find plants via contours. The numbering of each contour is done automatically based on its centroid coordinates and bounding box dimensions. Currently I have them sorted 'top-to-bottom', but it obviously isn't as perfect a sort as the manually-made grid. In addition, plant #1 may not stay plant #1 in the second or third image because each plant grows and moves over the course of the experiment, and new plants emerge and change the total number of contours (images are taken every hour for up to several weeks). Therefore, I cannot compare plant #1 in the first image and plant #1 in subsequent images because they may not even be the same plant.
How can I consistently number the same plant through the entire time-series using the second method? I considered associating centroids in subsequent images to (x,y) coordinates in the previous image that were the most similar (once the data is in tabular form), but this would fail to provide an updated numbered contour image.
The solution to this problem lay in automatic circle detection via the OpenCV Hough Transform function (cv2.HoughCircles()), finding the resulting Hough Circle centroids and then overlaying them on the original RGB image to create a reference key. As I did not have an image without any plants in it at all, I adapted the method so it found the correct amount of origins, but the result would be better in an image with no plants.
I converted the resulting csv files for the hough circles reference image (columns: OID, X, Y) and plant contours (columns: CID, X, Y, Area etc.) to GeoPandas GeoDataFrames and used Scipy's cKDTree to combine them through a nearest neighbour algorithm.
Special thanks to JHuw's answer in https://gis.stackexchange.com/questions/222315/geopandas-find-nearest-point-in-other-dataframe as Shapely's nearest_points function did not work for me.

Calculate 3D Plane that Rests on a 3D Surface

I have about 300,000 points defining my 3D surface. I would like to know if I dropped a infinitely stiff sheet onto my 3D surface, what the equation of that plane would be. I know I need to find the 3 points the sheet would rest on as that defines a plane, but I'm not sure how to find my 3 points out of the ~300,000. You can assume this 3D surface is very bumpy and that this sheet will most likely lie on 3 "hills".
Edit: Some more background knowledge. This is point cloud data for a scan of a 3D surface which is nearly flat. What I would like to know is how this object would rest if I flipped it over and put it on a completely flat surface. I realize that this surface may be able to rest on the table in various different ways depending on the density and thickness of the object but you can assume the number of ways is finite and I would like to know all of the different ways just in case.
Edit: After looking at some point cloud libraries I'm thinking of doing something like computing the curvature using a kd tree (using SciPy) and only looking at regions that have a negative curvature and then there should be 3+ regions with negative curvature so some combinatorics + iterations should give the correct 3 points for the plane(s).

Categories