Why is my geodataframe failing to reproject or buffer? - gis

PROBLEM: I am attempting to fill the extent of a shapefile with h3 polygons (resolution 4). Polyfill was giving us the incorrect amount of polygons (was only including polygons whose geographic center was within the shapefile), and so I needed another way to do this.
The solution we came up with was to read and buffer the shapefile using geopandas, then run the polyfill using h3pandas, and finally intersect the h3 layer with the original extent to retrieve any polygons of any depth we needed. However, whenever I run a buffer on a geographic-CRS extent, the buffer causes my RAM usage to exceed the 32gb I have available and the script crashes. The buffer works in a projected CRS, but if I reproject to a geographic CRS, the same thing happens where I run out of RAM.
STEPS: I have a shapefile that's being read as a geodataframe. The shapefile contains the borders of Latin America, so I'm setting the coordinate reference system to EPSG:31983. Next, I run a buffer on the file. This is where the script fails.
aoi = gpd.read_file("path/to/my/shapefile.shp") # Read shapefile
aoi = aoi.to_crs("EPSG:31983") # Set CRS
aoi_buff = aoi.buffer(3300) # Buffer gdf to 3.3km
FIXES TRIED: I thought perhaps the dataset itself was faulty, but verified it's not the dataset using QGIS and ArcMap. Next, I thought other parts of my code was wrong, but the code works fine against a smaller extent (Ukraine versus Latin America)... Ukraine works just fine. We tried not setting a CRS at all and having it set in QGIS before it ever got read into geopandas, but this didn't help. We also tried to simplify geometry to ease the strain of the buffer around Argentina:
aoi = gpd.read_file("path/to/my/shapefile.shp") # Read shapefile
aoi = aoi.to_crs("EPSG:31983") # Set CRS
aoi_simp = aoi.simplify(0.1, preserve_topology=False) # Simplify geometry
aoi_buff = aoi_simp.buffer(3300) # Buffer gdf to 3.3km
...but this didn't work either and yielded the same results.
Whats going on here? What am I doing wrong?

Related

How to train on single image depth estimation on KITTI dataset with masking method

I'm studying on a deep learning(supervised-learning) to estimate depth images from monocular images.
And the dataset currently uses KITTI data. RGB images (input image) are used KITTI Raw data, and data from the following link is used for ground-truth.
In the process of learning a model by designing a simple encoder-decoder network, the result is not so good, so various attempts are being made.
While searching for various methods, I found that groundtruth only learns valid areas by masking because there are many invalid areas, i.e., values that cannot be used, as shown in the image below.
So, I learned through masking, but I am curious about why this result keeps coming out.
and this is my training part of code.
How can i fix this problem.
for epoch in range(num_epoch):
model.train() ### train ###
for batch_idx, samples in enumerate(tqdm(train_loader)):
x_train = samples['RGB'].to(device)
y_train = samples['groundtruth'].to(device)
pred_depth = model.forward(x_train)
valid_mask = y_train != 0 #### Here is masking
valid_gt_depth = y_train[valid_mask]
valid_pred_depth = pred_depth[valid_mask]
loss = loss_RMSE(valid_pred_depth, valid_gt_depth)
As far as I can understand, you are trying to estimate depth from an RGB image as input. This is an ill-posed problem since the same input image can project to multiple plausible depth values. You would need to integrate certain techniques to estimate accurate depth from RGB images instead of simply taking an L1 or L2 loss between an RGB image and its corresponding depth image.
I would suggest you to go through some papers in estimating depth from single images such as: Depth Map Prediction from a Single Image using a Multi-Scale Deep Network where they use a network to first estimate the global structure of the given image and then use a second network that refines the local scene information. Instead of taking a simple RMSE loss, as you did, they use a scale-invariant error function in which the relationship between points is measured.

QGIS find points that are on or near a line

I'm trying to find all points that are on (or near < 10 m) from the lines in the below example.
These are two separate vector layers, I want to create a third layer, which is a subset of only the points on or near the lines i.e. removing the outliers.
In QGis I have been trying the following but have not been successful:
Vector > Geoprocessing Tools > Intersection
Vector > Research tools > Select by location
Vector > Data Management Tools > Join attributes by location
In the dialog boxes I've tried adjusting for intersection, and touching at different precisions.
None of these solutions gives the desired effect.
Any tips
This was what I did in the end, was a little convoluted but works:
1) Create buffer around road network and dissolve into a single polygon:
**Vector > Geoprocessing Tools > Fixed distance buffer **
input: Nnes
distance: 0.0001
segments = 100
dissolve = true
rename layer: buffer_lines
2) Create buffer around points:
**Vector > Geoprocessing Tools > Fixed distance buffer **
input: points
distance: 0.00001
segments = 100
dissolve = true
rename layer: buffer_points
3) Select buffer_points fully contained by buffer_lines.
**Vector > Research Tools > Select by location **
from: buffer_points
in: buffer_lines
within
4) Save selected features as new layer, by right clicking layer, and tick selected features only.
Create a buffer around the points. This buffer should be the distance from the line within which you wish to pick up points - in your case 10 metres. It will come in handy later on if you give each point a unique ID before this step (if not already done).
Take the intersections between the buffer and point layer. This will give you the sections of line which sit in these 10 metre buffers. The attributes table will tell you which point the buffer belongs to and which line it is intersected by.
Process in Excel to use the unique IDs to obtain which points sit within 10 metres of the line. You may wish to use a VLOOKUP() or INDEX(MATCH()) formula to obtain the point geometries from the original points layer.
My solution is using "join atributtes by nearest neighbor".
The first layer should be your point layer.
The second should be your lines layer.
IMPORTANT: The (optional) maximum distance would be 10m (in your case).
IMPORTANT: Check the "discard non matching" - this will discard all that are farther than the provided distance
You may or may not actually join atributtes but only the points that fit your maximum distance criteria will be exported to a newly created layer.

OpenAI gym: How to get pixels in CartPole-v0

I would like to access the raw pixels in the OpenAI gym CartPole-v0 environment without opening a render window. How do I do this?
Example code:
import gym
env = gym.make("CartPole-v0")
env.reset()
img = env.render(mode='rgb_array', close=True) # Returns None
print(img)
img = env.render(mode='rgb_array', close=False)
# Opens annoying window, but gives me the array that I want
print(img.shape)
PS. I am having a hard time finding good documentation for OpenAI gym. Is it just me, or does it simply not exist?
Edit: I don't need to ever open the render video.
I was curious about same so I started looking into the source code and this is what I found.
Open AI uses pyglet for displaying the window and animations.
For showing the animation everything is drawn on to window and then rendered.
And then pyglet stores what is being displayed on to a buffer.
Dummy version of how code is written in open AI
import pyglet
from pyglet.gl import *
import numpy as np
display = pyglet.canvas.get_display()
screen = display.get_screens()
config = screen[0].get_best_config()
pyglet.window.Window(width=500, height=500, display=display, config=config)
# draw what ever you want
#get image from the buffer
buffer = pyglet.image.get_buffer_manager().get_color_buffer()
image_data=buffer.get_image_data()
arr = np.frombuffer(image_data.get_data(),dtype=np.uint8)
print(arr)
print(arr.shape)
output:
[0 0 0 ... 0 0 0]
(1000000,)
so basically every image we get is from buffer of what is being displayed on the window.
So if we don't draw anything on window we get no image so that window is required to get the image.
so you need to find a way such that windows is not displayed but its values are stored in buffer.
I know its not what you wanted but I hope it might lead you to a solution.
I've just gone through half of the gym source code line by line, and I can tell you that 1, the observation space of cartpole is digits to the ai, not pixels. eg, from their cartpole env py file...
Observation:
Type: Box(4)
Num Observation Min Max
0 Cart Position -2.4 2.4
1 Cart Velocity -Inf Inf
2 Pole Angle -0.209 rad (-12 deg) 0.209 rad (12 deg)
3 Pole Angular Velocity -Inf Inf
So, the pixels are for you at this point. And 2, if your goal is to teach the ai on pixels, you will need to render images from your data-in array, then pass them THROUGH the observation space as a pixel array, like Maunish Dave shows. OpenAI's Atari version does this.
If you want a better guide, don't read the OpenAI Docs, read the Stable Baseline docs here: https://stable-baselines.readthedocs.io/
Someone offers an answer here:
https://github.com/openai/gym/issues/374
"The atari and doom environments give pixels in their observations (ie, the return value from step). I don't think any other ones do.
render produces different results on different OSes, so they're not part of any official environment for benchmarking purposes. But if you want to create a new environment where the observation is in pixels, you could implement it by wrapping an existing environment and calling render."
I'm also working on getting raw pixels as well and I'm trying to find a way to see if what has been returned is what I expect it is.
The documentation can be found:
https://gym.openai.com/docs
And a forum for discussing OpenAI:
discuss.openai.com
Although its not very lively.
I have faced the similar problem:
This is how fixed it, in rendering.py file at /gym/envs/classic_control find the following line in the Viewer class:
self.window = pyglet.window.Window(width=width, height=height, display=display)
Change this line to:
self.window = pyglet.window.Window(width=width, height=height, display=display, visible=False)
Hope it helps!!

Testing from an LMDB file in Caffe

I am wondering how to go about setting up ONLY a test phase in Caffe for an LMDB file. I have already trained my model, everything seems good, my loss has decreased, and the output I am getting on images loaded in one by one also seem good.
Now I would like to see how my model performs on a separate LMDB test set, but seem to be unable to do so successfully. It would not be ideal for me to do a loop by loading images one at a time since my loss function is already defined in caffe and this would require me to redefine it.
this is what I have so far, but the results of this dont make sense; when I compare the loss I have from the train set to the loss I get from this, they don't match (orders of magnitude apart). Does anyone have any idea what my problem could be?
caffe.set_device(0)
caffe.set_mode_gpu()
net = caffe.Net('/home/jeremy/Desktop/caffestuff/JP_Kitti/all_proto/mirror_shuffle/deploy_JP.prototxt','/home/jeremy/Desktop/caffestuff/JP_Kitti/all_proto/mirror_shuffle/snapshot_iter_10000.caffemodel',caffe.TEST)
solver = None # ignore this workaround for lmdb data (can't instantiate two solvers on the same data)
solver = caffe.SGDSolver('/home/jeremy/Desktop/caffestuff/JP_Kitti/all_proto/mirror_shuffle/lenet_auto_solverJP_test.prototxt')
niter = 100
test_loss = zeros(niter)
count = 0
for it in range(niter):
solver.test_nets[0].forward() # SGD by Caffe
# store the test loss
test_loss[count] = solver.test_nets[0].blobs['loss']
print(solver.test_nets[0].blobs['loss'].data)
count = count+1
See my answer here. Do not forget to subtract the mean, otherwise you'll get low accuracy. The link to the code, posted above, takes care of that.

Sketchup 3D Models, DEM and Netlogo GIS Extension

Bit of a challenge here which I've been grappling with for some time. I'll explain my full work flow so you can reproduce if needed.
I'm creating virtual landscapes in Google SketchUp which I ultimately would like to use in Netlogo to examine how turtles interact with them.
My problem is that by the time I get the landscapes into Netlogo the units don't seem to relate to the original 3D model.
Step 1: Create simple hill on a 50m by 50m square in Sketchup using the Toposhaper extension.
Step 2: Export to .dae file and import into Meshlab, ensure the Meshlab model has the same dimensions as the Sketchup model by adjusting the units with the assistance of the measuring tool. Export from meshlab as .xyz file.
Step 3: Import .xyz file into QGis as points by adding a new layer from delimited file. Selecting field_1 and field_2 as X and Y fields.
Step 4: Create raster of points using Raster > Interpolation > Interpolation. Add field_3 as interpolation attribute, set number of columns to 50 by 50 (to correspond to the 50m x 50m 3D model), adjust cell size X and Y to match to ensure Netlogo will read the resulting .asc file.
Step 5: Finally, I setup a model in Netlogo to receive the raster. Firstly, in model settings I set the the min and max pxor and pycor to 0 and 50. Then, using the Gis Extension, I import the raster apply the z-value to a patch variable called elevation:
to load-gis
set elevation gis:load-dataset "cone_50.asc"
gis:set-world-envelope-ds gis:envelope-of elevation
gis:apply-raster elevation target-elev
end
Now, each patch of my 50 by 50 Netlogo world should have an elevation value taken from my 50 by 50 raster. In theory, adding all the elevation values together should (roughly) give me the total volume of the raised area of the hill? The figure I get is higher however and the problem gets worse with larger volumes.
Can anyone help?