from numpy import mean
import os
from os import makedirs,chdir
from os.path import exists

"""
Explanation: Team: Satoshi Nakamoto <br>
Names: Alex Levering & Hèctor Muro <br>
Lesson 10 Exercise solution
Import standard libraries
End of explanation
"""


from osgeo import ogr,osr
import folium
import simplekml

"""
Explanation: Import non-standard libraries (install as needed)
End of explanation
"""


if not exists('./data'):
    makedirs('./data')

chdir("./data")

"""
Explanation: Optional directory creation
End of explanation
"""


driverName = "ESRI Shapefile"
drv = ogr.GetDriverByName( driverName )
if drv is None:
    print "%s driver not available.\n" % driverName
else:
    print  "%s driver IS available.\n" % driverName

"""
Explanation: Is the ESRI Shapefile driver available?
End of explanation
"""


def shpFromPoints(filename, layername, points, save_kml = True):
    spatialReference = osr.SpatialReference()
    spatialReference.ImportFromProj4('+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs')
    ds = drv.CreateDataSource(filename)
    layer=ds.CreateLayer(layername, spatialReference, ogr.wkbPoint)
    layerDefinition = layer.GetLayerDefn()
    
    point = ogr.Geometry(ogr.wkbPoint)
    feature = ogr.Feature(layerDefinition)
    
    kml = simplekml.Kml()
    for i, value in enumerate(points):
        point.SetPoint(0,value[0], value[1])
        feature.SetGeometry(point)
        layer.CreateFeature(feature)
        kml.newpoint(name=str(i), coords = [(value[0],value[1])])
    ds.Destroy()        
    if save_kml == True:
        kml.save("my_points2.kml")

"""
Explanation: Define a function which will create a shapefile from the points input and export it as kml if the option is set to True.
End of explanation
"""


filename = "wageningenpoints.shp"
layername = "wagpoints"
pts = [(5.665777,51.987398),
        (5.663133,51.978434)]
shpFromPoints(filename, layername, pts)

"""
Explanation: Define the file and layer name as well as the points to be mapped.
End of explanation
"""


def mapFromPoints(pts, outname, zoom_level, save = True):
    mean_long = mean([pt[1] for pt in pts])
    mean_lat = mean([pt[0] for pt in pts])
    point_map = folium.Map(location=[mean_long, mean_lat], zoom_start = zoom_level)
    for pt in pts:
        folium.Marker([pt[1], pt[0]],\
        popup = folium.Popup(folium.element.IFrame(
        html='''
                <b>Latitude:</b>  {lat}<br>
                <b>Longitude:</b> {lon}<br>
             '''.format(lat = pt[1], lon = pt[0]),\
        width=150, height=100),\
        max_width=150)).add_to(point_map)
    if save == True:
        point_map.save("{}.html".format(outname))
    return point_map

"""
Explanation: Define a function to create a nice map with the points using folium library.
End of explanation
"""


mapFromPoints(pts, "SatoshiNakamotoMap", zoom_level = 15)

"""
Explanation: Call the function specifying the list of points, the output map name and its zoom level. If not False, the map is saved as an html
End of explanation
"""


