import fiona
import numpy as np
from shapely.geometry import shape
# extraction des point x,y du fichier shapefile
x, y = zip(*[(shape(point['geometry']).x, shape(point['geometry']).y) for point in fiona.open('points.shp'])
# calcul de la matrice de covariance de Wang et al. (2015)
x = np.array(x)
y = np.array(y)
meanx = np.mean(x)
meany = np.mean(y)
n = len(x)
# calul de la matrice (basée sur n)
xd = x-meanx
yd = y-meany
xyw= sum(xd*yd)
x2w = sum(np.power(xd,2))
y2w = sum(np.power(yd,2))
cov = np.array([[x2w, xyw],[xyw,y2w]])/len(x)
print cov
[[ 11394.1712941 2160.35998689]
[ 2160.35998689 2441.06326772]]
# extraction des valeurs et vecteurs propres
eigenval,eigenvec = np.linalg.eig(cov)
# rayons de l'ellipse (racine carrée des valeurs proprez
sigmay,sigmax = np.sqrt(eigenval)
print sigmax, sigmay
[ 44.12521625 109.03302185 ]
# angle de l'ellipse à partir des vecteurs propres
theta = 90 - np.rad2deg(np.arccos(eigenvec[0, 0]))
print theta
77.1191513516
# aire de l'ellipse
aire = np.pi * sigmax*sigmay
print aire
16194.143806210201
# excentricité de l'ellipse
exc = np.sqrt(1 - ((min(sigmax,sigmay)**2)/(max(sigmax,sigmay)**2)))
print exc
0.91445132916786864
# solution présentée par Wang et al(2015)
B = np.sqrt(np.power(x2w - y2w, 2) + 4 * np.power(xyw, 2))
sigma2 = np.sqrt(((x2w + y2w) + B) / (2 * n))
sigma1= np.sqrt(((x2w + y2w) - B) / (2 * n))
print sigma1,sigma2
44.1252162467 109.033021847
# angles de l'ellipse
print np.degrees(np.arctan(((x2w - y2w) + B)/(2*xyw))), np.degrees(np.arctan(((x2w - y2w) - B)/(2*xyw)))
77.1191513516 -12.8808486484