I'm trying to use cartopy to plot several maps and I want to use them offline. Cartopy has a data directory,
import cartopy.config
cartopy.config
{'data_dir': '/home/user/.local/share/cartopy',
'downloaders': {('shapefiles',
'gshhs'): <cartopy.io.shapereader.GSHHSShpDownloader at 0x7f3ee33ee7d0>,
('shapefiles',
'natural_earth'): <cartopy.io.shapereader.NEShpDownloader at 0x7f3ee33ee710>},
'pre_existing_data_dir': '',
'repo_data_dir': '/home/user/bin/virtualenvs/mobi/local/lib/python2.7/site-packages/cartopy/data'}
So I believe that i can download the maps from Natural Earth site. How can I structure this data on this directory so cartopy would not use the internet to plot? And how can I do the same for OpenStreetMap data?
(Partial answer only)
At Natural Earth web site, http://www.naturalearthdata.com/downloads/, you can find all the downloadable files.
For example, this link provides low resolution data: http://www.naturalearthdata.com/downloads/110m-physical-vectors/
One of the data files on that page has this link address:
http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/110m/physical/ne_110m_coastline.zip
This piece of code will download that file (if it is not readily available on the computer):-
import cartopy
fname = cartopy.io.shapereader.natural_earth( \
resolution='110m', \
category='physical', \
name='110m_coastline')
fname is full pathname of the downloaded file.
You dont need to arrange the download location for cartopy. It already has default location that you can find by:
cartopy.config['data_dir'] # usually 'C:\\Users\\username\\.local\\share\\cartopy'
You can check out the files you downloaded and see how they are structured in that location.
Next time when you use cartopy function cartopy.io.shapereader.natural_earth (with default config) it will use the local files if they are available.
I had Faced similar issue wherein, with cartopy, the plt.gca().coastlines() was triggering the download of a zip file from external server, but the download was failing as internet connectivity was absent.
/home/apps/CARTOPY/0.16.0/lib64/python2.7/site-packages/Cartopy-0.16.0-py2.7-linux-x86_64.egg/cartopy/io/__init__.py:260: DownloadWarning: Downloading: http://naciscdn.org/naturalearth/110m/physical/ne_110m_coastline.zip
warnings.warn('Downloading: {}'.format(url), DownloadWarning)
I manually downloaded the zip file , and extracted under - ~/.local/share/cartopy/shapefiles/natural_earth/physical.
~/.local/share/cartopy/shapefiles/natural_earth/physical> ls
ne_110m_coastline.README.html ne_110m_coastline.cpg ne_110m_coastline.prj ne_110m_coastline.shx
ne_110m_coastline.VERSION.txt ne_110m_coastline.dbf ne_110m_coastline.shp
then after renaming/removing "ne_" prefix from some files, i was able to solve this issue.
~/PLOT_TEST> ls ~/.local/share/cartopy/shapefiles/natural_earth/physical/
110m_coastline.cpg 110m_coastline.dbf 110m_coastline.prj 110m_coastline.shp 110m_coastline.shx ne_110m_coastline.README.html ne_110m_coastline.VERSION.txt
I have prepared a code in where you can download the the shapefiles from natural earth and then convert them into a dataframe. Pay attention, the country coordinates in natural earth are in polygon and multi-polygon format. In the case of dealing with Rivers which are linestring you need to modify the code.
You might need to manipulate the "name" with your desired filename like "coastlines". Find more information in the following link:
https://www.naturalearthdata.com/downloads/
import cartopy.io.shapereader as shpreader
ne_earth_countries = shpreader.natural_earth(resolution = '10m',
category = 'cultural',
name='admin_0_countries')
countries = shpreader.Reader(ne_earth_countries).records()
def extract_geom_meta(country):
coords = np.empty(shape=[0,2])
for geom in country.geometry:
coords = np.append(coords, geom.exterior.coords, axis=0)
country_name = country.attributes["ADMIN"]
return [country_name, coords]
WorldDF = pd.DataFrame([extract_geom_meta(country) for country in countries],
columns=['countries','coordinates'])
CountryDF = pd.concat([pd.DataFrame(WorldDF['coordinates'][country_idx])
for country_idx in range(len(WorldDF))]).reset_index()
CountryDF['Label'] = CountryDF.apply(lambda row: 1 if row['index'] == 0
else 0,axis=1).cumsum()-1
CountryDF['Country'] = CountryDF['Label'].apply(lambda row: WorldDF.countries[row])
CountryDF.rename(columns={0:'Longitude', 1:'Latitude'},inplace=True)
print(CountryDF.head())
Related
I need to create a Wind Rose KML file to be opened in google earth with as (similar to) the following pictures.
I can create wind roses using windrose python module, like this one:
And I know how to create KML points and lines in python using simplekml module like this one:
Does anyone know any package capable of doing that?
or any idea of how to do it?
If you use matplotlib when draw windrose, try to save the fig with following opthons.
plt.axis('off')
plt.savefig('windrose.png', bbox_inches='tight', pad_inches=0, transparent=True)
After you got the image file, generate ground overlay code in kml.
import simplekml
kml = simplekml.Kml(open=1)
doc = kml.newdocument(name='sample', open=1, visibility=0)
ground = doc.newgroundoverlay(name='windrose example')
ground.icon.href = 'windrose.png'
ground.altitudemode = simplekml.AltitudeMode.absolute
ground.altitude = 500.0
ground.latlonbox.north = 38.031368255615234
ground.latlonbox.south = 37.11344909667969
ground.latlonbox.east = 141.5791015625
ground.latlonbox.west = 140.4208984375
ground.visibility = 1
kml.save('sample.kml')
Each values are need to adjust.
Please refer following, if you'd like to know more about ground overlay.
https://developers.google.com/kml/documentation/altitudemode#absolute
Open Google Earth.
Draw a static picture\chart like wanted one over a map.
Save it into a KML file.
Open with any text editor.
It must show you an example which lead you to generate a valid KML with your data.
So I have this bit of code, which clips out a shapefile of a tree out of a Lidar Pointcloud. When doing this for a single shapefile it works well.
What I want to do: I have 180 individual tree shapefiles and want to clip every file out of the same pointcloud and save it as a individual .las file.
So in the end I should have 180 .las files. E.g. Input_shp: Tree11.shp -> Output_las: Tree11.las
I am sure that there is a way to do all of this at once. I just dont know how to select all shapefiles and save the output to 180 individual .las files.
Im really new to Python and any help would be appreciated.
I already tried to get this with placeholders (.format()) but couldnt really get anywhere.
from WBT.whitebox_tools import WhiteboxTools
wbt = WhiteboxTools()
wbt.work_dir = "/home/david/Documents/Masterarbeit/Pycrown/Individual Trees/"
wbt.clip_lidar_to_polygon(i="Pointcloud_to_clip.las", polygons="tree_11.shp", output="Tree11.las")
I don't have the plugin you are using, but you may be looking for this code snippet:
from WBT.whitebox_tools import WhiteboxTools
wbt = WhiteboxTools()
workDir = "/home/david/Documents/Masterarbeit/Pycrown/Individual Trees/"
wbt.work_dir = workDir
# If you want to select all the files in your work dir you can use the following.
# though you may need to make it absolute, depending on where you run this:
filesInFolder = os.listDir(workDir)
numberOfShapeFiles = len([_ for _ in filesInFolder if _.endswith('.shp')])
# assume shape files start at 0 and end at n-1
# loop over all your shape files.
for fileNumber in range(numberOfShapeFiles):
wbt.clip_lidar_to_polygon(
i="Pointcloud_to_clip.las",
polygons=f"tree_{fileNumber}.shp",
output=f"Tree{fileNumber}.las"
)
This makes use of python format string templates.
Along with the os.listdir function.
I am using Google's Earth Engine API to access LandSat images.
The program is as given below,
import ee
ee.Initialize()
Load a landsat image and select three bands.
landsat = ee.Image('LANDSAT/LC8_L1T_TOA
/LC81230322014135LGN00').select(['B4', 'B3', 'B2']);
Create a geometry representing an export region.
geometry = ee.Geometry.Rectangle([116.2621, 39.8412, 116.4849, 40.01236]);
Export the image, specifying scale and region.
export.image.toDrive({
image: landsat,
description: 'imageToDriveExample',
scale: 30,
region: geometry
});
it throws the following error.
Traceback (most recent call last):
File "e6.py", line 11, in <module>
export.image.toDrive({
NameError: name 'export' is not defined
Please Help. I am unable to find the right function to download images.
If you are using the python API, you have to use the 'batch' submodule. The default behaviour is to save to your google drive. You can specify your bounding box as a list of coordinates as well:
llx = 116.2621
lly = 39.8412
urx = 116.4849
ury = 40.01236
geometry = [[llx,lly], [llx,ury], [urx,ury], [urx,lly]]
task_config = {
'description': 'imageToDriveExample',
'scale': 30,
'region': geometry
}
task = ee.batch.Export.image(landsat, 'exportExample', task_config)
task.start()
This should generate a file called 'exportExample.tif' in your GoogleDrive top folder.
Also note that the semicolons at the end of each line are not necessary in python.
To build on Ben's answer, you can also use:
geometry = ee.Geometry.Rectangle([116.2621, 39.8412, 116.4849, 40.01236])
from your original post, but add the following line beneath it so the coordinates are in the correct format for the task_config-->Region field:
geometry = ee.Geometry.Rectangle([116.2621, 39.8412, 116.4849, 40.01236])
geometry = geometry['coordinates'][0]
It prevents a "task_config" formatting mismatch when you get to here:
task = ee.batch.Export.image(landsat, 'exportExample', task_config)
This will allow you to use the given function from the API, but it will extract the coordinates in such a way that you can use them in the approach suggested by Ben above.
There is a typo in your code, Export should start from the capital letter. See documentation.
Where do you specify the dates? Is there any good, quick, documentation or tutorial for Python? seems there are plenty about JavaScript one!
There is good, quick example of python api.You can check this link. There is 1 post for download satellite image using python api.
I am running a query to select a polygon from a set of polygons. Then I input that polygon into a feature dataset in a geodatabase. I then use this polygon(or set of polygons) to dissolve to get the boundary of the polygons and the centroid of the polygon(s), also entered into separate feature datasets in a geodatabase.
import arcpy, os
#Specify the drive you have stored the NCT_GIS foler on
drive = arcpy.GetParameterAsText(0)
arcpy.env.workspace = (drive + ":\\NCT_GIS\\DATA\\RF_Properties.gdb")
arcpy.env.overwriteOutput = True
lot_DP = arcpy.GetParameterAsText(1).split(';')
PropertyName = arcpy.GetParameterAsText(2)
queryList= []
for i in range(0,len(lot_DP)):
if i % 2 == 0:
lt = lot_DP[i]
DP = lot_DP[i+1]
query_line = """( "LOTNUMBER" = '{0}' AND "PLANNUMBER" = {1} )""".format(lt, DP)
queryList.append(query_line)
if i < (len(lot_DP)):
queryList.append(" OR ")
del queryList[len(queryList)-1]
query = ''.join(queryList)
#Feature dataset for lot file
RF_Prop = drive + ":\\NCT_GIS\\DATA\\RF_Properties.gdb\\Lots\\"
#Feature dataset for the property boundary
RF_Bound = drive + ":\\NCT_GIS\\DATA\\RF_Properties.gdb\\Boundary\\"
#Feature dataset for the property centroid
RF_Centroid = drive + ":\\NCT_GIS\\DATA\\RF_Properties.gdb\\Centroid\\"
lotFile = drive + ":\\NCT_GIS\\DATA\\NSWData.gdb\\Admin\\cadastre"
arcpy.MakeFeatureLayer_management(lotFile, "lot_lyr")
arcpy.SelectLayerByAttribute_management("lot_lyr", "NEW_SELECTION", query)
#Create lot polygons in feature dataset
arcpy.CopyFeatures_management("lot_lyr", RF_Prop + PropertyName)
#Create property boundary in feature dataset
arcpy.
arcpy.Dissolve_management(RF_Prop + PropertyName , RF_Bound + PropertyName, "", "", "SINGLE_PART", "DISSOLVE_LINES")
#Create property centroid in feature dataset
arcpy.FeatureToPoint_management(RF_Bound + PropertyName, RF_Centroid + PropertyName, "CENTROID")
Every time I run this I get an error when trying to add anything to the geodatabase EXCEPT when copying the lot layer into the geodatabase.
I have tried not copying the lots into the geodatabase and copying it into a shapefile and then using that but still it the boundary and centroid will not import into the geodatabase. I tried outputing the boundaries into shapefiles then using the FeatureClassToGeodatabase tool but still I get error after error.
If anyone can shed light on this It would be grateful
In my experience, I found out that if I had recently opened then closed ArcMap or ArcCatalog it would leave two ArcGIS services running (check task manager) even though I had closed ArcMap and ArcCatalog. If I tried running a script while these two services were running I would get this error. Finding these services in Windows task manager and ending them fixed this error for me. The two services were
ArcGIS cache manager
ArcGIS online services
I've also heard that your computer's security/anti-virus software may possibly interfere with scripts running. So adding your working directory as an exception to your security software may also help.
If in the rare occasions that this didn't work I just had to restart the computer.
I'm trying to render a map using mapnik and python from a GPS track recorded. I get the gps data from a Database, so it is just an array (lat, long).
Does anyone knows an example for doing that? I know I need to create a shape file first, but I'm new to mapnik and I don't really understand it so far. maybe with a good example I will get it :-)
Thanks
The simplest method would actually be to use a KML file. Install the simplekml module and then run through your array to create the KML file.
import simplekml
kml = simplekml.Kml()
for i, coord in enumerate(coords):
# assuming coord is a lat, lon tuple
kml.newpoint(name="Point %s" % i, coords=[coord])
kml.save("GPS_tracking_data.kml")
Now you can load that into mapnik as a datasource and plot it;
import mapnik
# Setup the map
map_canvas = mapnik.Map(width_in_px, height_in_px)
map_canvas.background = mapnik.Color('rgb(0,0,0,0)') # transparent
# Create a symbolizer to draw the points
style = mapnik.Style()
rule = mapnik.Rule()
point_symbolizer = mapnik.MarkersSymbolizer()
point_symbolizer.allow_overlap = True
point_symbolizer.opacity = 0.5 # semi-transparent
rule.symbols.append(point_symbolizer)
style.rules.append(rule)
map_canvas.append_style('GPS_tracking_points', style)
# Create a layer to hold the ponts
layer = mapnik.Layer('GPS_tracking_points')
layer.datasource = mapnik.Ogr(file="GPS_tracking_data.kml", layer_by_index=0)
layer.styles.append('GPS_tracking_points')
map_canvas.layers.append(layer)
# Save the map
map_canvas.zoom_all()
mapnik.render_to_file(map_canvas, 'GPS_tracking_points.png', 'png')
That should just about do it. The docs for python+mapnik are a little weak but you should be able to build on this if you reference;
The mapnik wiki
The python mapnik package docs