Is there a way to embed Google Earth or Google Earth Engine in a Python desktop application?
As of now, I've created a kml file with longitude/latitude data that can be manually dropped into Google Earth Pro to trace the path of the GPS.
I've seen a lot of forum posts where Google Earth was embedded in webpages but not desktop applications so I was wondering if it could be done.
Any suggestions would be appreciated
Yes, you can add Google Earth Engine results to a desktop application as long as it supports WMS tile layers, images, or graphs.
Here are some examples assuming your have already gone through these preprocesing steps:
import ee
ee.Initialize() # note: may have initialize with a service account within an application
# ee Image object of the Global SRTM data
img = ee.Image("USGS/SRTMGL1_003")
Get WMS tiles:
# get map tile id and token with specific color palette
# arguments into "getMapId" are the same as the JavaScript API "Map.addLayer"
result = img.getMapId({'min': 0, 'max': 3000})
url = "https://earthengine.googleapis.com/map/{mapid}/{{z}}/{{x}}/{{y}}?token={token}"
tiles = url.format(**result)
print(tiles)
# visualize in your favorite application that supports WMS
Get static Image:
# Generate a URL that displays a static Image from Global DEM
url = img.getThumbUrl({'min':0, 'max':3000})
# create a file-like object from the url
import urllib2
f = urllib2.ulropen(url)
# Display the image using matplotlib
import matplotlib.pyplot as plt
result = plt.imread(f)
plt.imshow(result)
plt.show()
Displaying a time series graph may be a little more involved:
# get a collection with time series
collection = ee.ImageCollection('MODIS/006/MOD11A2')\
.filterDate('2016-01-01','2018-01-01')
# create a geometry of area to show time series
atl = ee.Geometry.Point([-84.3880,33.7490])
# get a time series over the point
result = collection.select('LST_Day_1km').getRegion(atl,1000).getInfo()
# turn the result into a pandas dataframe and manipulate results for plotting
import pandas as pd
df = pd.DataFrame(result[1:])
df.columns = result[0]
# convert epoch time to a format for pandas
dates = [pd.Timestamp(t*1000000) for t in df.time]
# make new pandas series object with scaled LST values
ts = pd.Series(np.array(df.LST_Day_1km)*0.02-273.15,index=dates,name='lst')
ts.index.name = 'Date'
# finally display results
ts.plot()
There are probably more efficient ways to get the results and display in an application, however, this may be a way to get you started.
Two second google search found this! So in answer to your question, yes you can use Google Earth in Python
https://developers.google.com/earth-engine/python_install
Related
I am trying to replicate the Glaciers Demo using an Xarray of geospatial data. I am able to create pretty much exactly what I want but I am trying to create a Panel app that allows the user to select the data_vars, each of which has different dimensions that I want make interactable, and visualize on an interactive map with at least the continents contour. Here is what my Xarray Dataset looks like :
def plot(field):
return xds[field].hvplot.image().opts(cmap='jet',height=650,width=1300,data_aspect=1)
interact(plot, field = list(xds.data_vars))
and here is what the code above produces in a notebook :
I would like to integrate the selector for the data_vars and then depending on its dimensions have interactive maps with controls for all its dimensions (ES has (time, pres1, lat, lon) while P0 has only (time, lat, lon)) and I would like to have the controls in the sidebar and the plots in the main of the following template :
from turtle import width
from matplotlib.pyplot import title
import panel as pn
import numpy as np
import holoviews as hv
from panel.template import DefaultTheme
from pathlib import Path
import fstd2nc
import hvplot.xarray
import xarray as xr
from unicodedata import name
import hvplot
import param
from panel.interact import interact
pn.extension(sizing_mode='stretch_width')
bootstrap = pn.template.MaterialTemplate(title='Material Template', theme=DefaultTheme, )
glob_path = Path(r"C:\Users\spart\Documents\Anaconda-Work-Dir")
file_list = [str(pp).split('\\')[-1] for pp in glob_path.glob("2022*")]
phase = pn.widgets.FloatSlider(name="Phase", start=0, end=np.pi)
fileSel = pn.widgets.Select(name='Select File', options=file_list)
#pn.depends(fileSel=fileSel)
def selectedFile(fileSel):
base_path = r"C:\Users\spart\Documents\Anaconda-Work-Dir\{}".format(fileSel)
return pn.widgets.StaticText(name='Selected', value=base_path)
#pn.depends(fileSel=fileSel)
def dataXArray(fileSel):
base_path = r"C:\Users\spart\Documents\Anaconda-Work-Dir\{}".format(fileSel)
xds = fstd2nc.Buffer(base_path).to_xarray()
return xds.ES.hvplot( width=500)
bootstrap.sidebar.append(fileSel)
bootstrap.sidebar.append(selectedFile)
bootstrap.main.append(
pn.Row(
pn.Card(hv.DynamicMap(dataXArray), title='Plot'),
)
)
bootstrap.show()
EDIT : Here is a link to an example dataset which can be loaded with the following code
xds = fstd2nc.Buffer(PATH_TO_FILE).to_xarray()
Without the data file I can't easily run the code, but some observations:
If using bare functions like this rather than classes, I'd recommend using pn.bind rather than pn.depends; it really helps get the code organized better.
For a simple application like this, I'd use hvPlot .interactive: https://hvplot.holoviz.org/user_guide/Interactive.html
I can't seem to find this in the docs, but you can pull out the widgets from the result of dataXArray (or any other hvplot or holoviews object) using .widgets(), and you can then put that in the sidebar. You can then pull out just the plot using .panel(), and put that in the main area.
If that helps you get it done, then great; if not please post a sample data file or two so that it's runnable, and I can look into it further. And please submit a PR to the docs once you get it working so that future users have less trouble!
I'm trying to plot some points on a map, and when searching on the internet, I found [this][1] tutorial with Google Maps and Bokeh library. The problem is that, after doing all the steps to get a key in google api, to set the environment variable, when I try to plot, it says that google maps weren't able to load.
Since I don't have much time, and I really need to plot some data (UTM coordinates, that I Intend to transform to latitude and longitude with pyproj), I was wondering if someone knows, another library, with examples, easy to work, with where I could plot my data (is a pandas dataframe with East, Northing, Elevation).
This is the code from the example I'm trying to reproduce:
import os
ACCESS_KEY_ID = os.environ.get('ACCESS_KEY_ID')
api_key = os.environ['SECRET_ACCESS_KEY']
import pandas as pd
from bokeh.io import output_notebook
df = pd.read_csv('dvf_gex.csv')
lat, lon = 46.2437, 6.0251
from bokeh.io import show
from bokeh.plotting import gmap
from bokeh.models import GMapOptions
bokeh_width=500
bokeh_height=500
def plot(lat, lng, zoom=10, map_type='roadmap'):
gmap_options = GMapOptions(lat=lat, lng=lng,
map_type=map_type, zoom=zoom)
p = gmap(api_key, gmap_options, title='Pays de Gex',
width=bokeh_width, height=bokeh_height)
show(p)
return p
this is the error I got:
[![enter image description here][2]][2]
The error I get on my browser console is:
[![enter image description here][3]][3]
I have activated the Maps Embed API, is that enough? should I have another API activated?
[1]: https://thedatafrog.com/en/articles/show-data-google-map-python/#commento-login-box-container
[2]: https://i.stack.imgur.com/SxoXS.png
[3]: https://i.stack.imgur.com/rjqc2.png
I guess Google has retired the GMap version that Bokeh 2.4.2 specifies by default? That is pretty annoying and user-unfriendly of them. However, you can specify any API version to use by passing it to gmap, e.g.
gmap(api_key, api_version="3.47", ...)
I'm attempting to grab an image of diagrams constructed within a rectangle on a power point slide deck. I found python-pptx and am able to identify the shapes on each slide. Is there any way to expand this to take a snapshot of the area within the rectangle shape and export it as an image?
# Auto grab the photos created in Powerpoint
from pptx import Presentation
prs = Presentation('ex.pptx')
for slide in prs.slides:
print(slide)
for shape in slide.shapes:
print(shape)
# Identify shape on each slide, find area within, and save as .png
I think you're going to be best off looking at a COM32 type of solution, either writing something in VBA or possibly using the win32com library in Python if you really want a Python solution.
Either way this is going to fire up a "live" PowerPoint application instance and basically run it by remote control. That sort of thing isn't a great idea server-side, but if it's just for personal productivity it might work fine.
python-pptx can't do this sort of thing and probably never will. The rendering engine needs to get involved in this type of work and python-pptx is strictly a .pptx file editor/generator.
With Aspose.Slides for Python, you can easily save presentation shapes to images. The following code example shows you how to save all charts from a presentation to PNG images:
import aspose.slides as slides
import aspose.slides.charts as charts
import aspose.pydrawing as draw
with slides.Presentation("example.pptx") as presentation:
for slide_index, slide in enumerate(presentation.slides):
for shape_index, shape in enumerate(slide.shapes):
# Looking for charts, for example.
if isinstance(shape, charts.Chart):
# Get a chart image.
with shape.get_thumbnail() as chart_image:
# Save the chart image to PNG.
image_path = "chart_image_{}_{}.png".format(slide_index, shape_index)
chart_image.save(image_path, draw.imaging.ImageFormat.png)
Aspose.Slides for Python is a paid product, but you can get a temporary license or use it in a trial mode to evaluate all features for managing presentations. Alternatively, you can use Aspose.Slides Cloud SDK for Python. This package provides a REST-based API for managing presentations as well. The code example below shows you how to do the same using Aspose.Slides Cloud:
import asposeslidescloud
import aspose.pydrawing as draw
from asposeslidescloud.apis.slides_api import SlidesApi
from asposeslidescloud.models import *
slides_api = SlidesApi(None, "my_client_id", "my_client_secret")
file_name = "example.pptx"
# Upload the presentation to the default storage.
with open(file_name, "rb") as file_stream:
slides_api.upload_file(file_name, file_stream)
# Get the number of slides.
slides_info = slides_api.get_slides(file_name)
slide_count = len(slides_info.slide_list)
for slide_index in range(1, slide_count + 1):
# Get the number of shapes on the current slide.
shapes_info = slides_api.get_shapes(file_name, slide_index)
shape_count = len(shapes_info.shapes_links)
for shape_index in range(1, shape_count + 1):
shape = slides_api.get_shape(file_name, slide_index, shape_index)
# Looking for charts, for example.
if shape.type == "Chart":
# Get the chart as a PNG image.
image_path = slides_api.download_shape(file_name, slide_index, shape_index, ShapeExportFormat.PNG)
print("A chart image was saved to " + image_path)
This is also a paid product, but you can make 150 free API calls per month for any purposes.
I work as a Support Developer at Aspose and can answer your questions of these libraries on Aspose.Slides forum.
I'm plotting the missions ran by the USAF on North Korea during the Korean War.
The following is the map with 2800 plots.
I have a total of about 7500 plots, but whenever I try to plot above 2800 a blank map renders. I'm rendering on a pc laptop. Would it render if I use a desktop? Or is this a limit with folium?
I'm not speculating that it's an issue with the data. I'll share the coordinates data in case someone would like to explore it: link to public excel sheet.
As #Bob Haffner suggested you can use FastMarkerCluster from Folium library.
Here is my code, in my file there is ~500K points.
import pandas as pd
import json
from folium.plugins import FastMarkerCluster
rome_lat, rome_lng = 41.9028, 12.4964
with open("file_name.json", 'r') as f:
# create a new DataFrame
samples = pd.DataFrame(json.loads(f.read()))
# init the folium map object
my_map = folium.Map(location=[rome_lat, rome_lng], zoom_start=5)
# add all the point from the file to the map object using FastMarkerCluster
my_map.add_child(FastMarkerCluster(samples[['latitude', 'longitude']].values.tolist()))
# save the map
my_map.save("save_file.html")
This code takes ~10ms to render the map.
For more details example please follow this link:
FastMarkerCluster example
Hope this is helpful.
Another option is that we can add a specific number of markers(let's say 3000 markers) on a layer, using folium.map.FeatureGroup() function that will add 3000 markers on a single layer, and we can add that layer to the map using add_child() function, which reduces the number of layers on the map. I got the result for 20,000 Markers and 3000 line string. And is able to load within 40-45 seconds.
I made this code in python 2.7 for downloading bing traffic flow map (specific area) every x minutes.
from cStringIO import StringIO
from PIL import Image
import urllib
import time
i = 1
end = time.time() + 60*24*60
url = 'https://dev.virtualearth.net/REST/V1/Imagery/Map/AerialWithLabels/45.8077453%2C15.963863/17?mapSize=500,500&mapLayer=TrafficFlow&format=png&key=Lt2cLlR9OcfEnMLv5qyd~YbPpC6zOQdhTMcwsKCwlgQ~Am2YLG00hHI6h7W1IPq31VOzqEXKAhedzHfknCejIrdQF_iVrQS82AUdjBT0YMtt'
while True:
buffer = StringIO(urllib.urlopen(url).read())
image = Image.open(buffer)
image.save('C:\Users\slika'+str(i)+'.png')
i=i+1
if time.time()>end:
break
time.sleep(60*10)
This is one of the images i got traffic flow
Now my question is can i convert only traffic flow lines (green,yellow, orange, red) and assign them attributes (1,2,3,4) or ('No traffic' , 'Light' , 'Moderate' , 'Heavy') into shape file for usage in QGIS. What modules should i look for and is it even possible. Any idea or sample code would be much helpful.
This is against the terms of use of Bing Maps.
Also, I notice that you are using a Universal Windows App key. Those keys are to only be used in public facing Windows apps that anyone has access to. These keys cannot be used in GIS/business apps. Use a Dev/Test key or upgrade to an Enterprise account.