meteortools.utils.getOverlappingFovs

  1# Copyright (C) 2018-2023 Mark McIntyre
  2# 
  3#
  4import os
  5import glob
  6import xmltodict
  7
  8from shapely.geometry import Polygon
  9from shapely.geometry import Point
 10
 11
 12def _munchKML(kmlFilename):
 13    """ Private function to work around circular dependency 
 14    """
 15    with open(kmlFilename) as fd:
 16        x = xmltodict.parse(fd.read())
 17        cname = x['kml']['Folder']['name']
 18        coords = x['kml']['Folder']['Placemark']['MultiGeometry']['Polygon']['outerBoundaryIs']['LinearRing']['coordinates']
 19        coords = coords.split('\n')
 20        ptsarr=[]
 21        for lin in coords:
 22            s = lin.split(',')
 23            ptsarr.append((float(s[0]), float(s[1])))
 24        polyg = Polygon(ptsarr)
 25        return cname, polyg 
 26
 27
 28def pointInsideFov(latDegs,lngDegs, kmlFilename):
 29    """
 30    Test if a point is inside the field of view of a KML file. Useful for testing which 
 31    cameras might have seen an event at a known location.  
 32
 33    Arguments:  
 34        latDegs:        [degrees] latitude of the point  
 35        lngDegs:        [degrees] latitude of the point  
 36        kmlFileName:    [str] full path to the KML file to test  
 37
 38    Returns:  
 39        True or False  
 40    """
 41
 42    c1, p1 = _munchKML(kmlFilename)
 43    pt = Point(latDegs, lngDegs)
 44    return p1.contains(pt)
 45
 46
 47def checkKMLOverlap(kmfile1, kmfile2):
 48    """
 49    Test if two KML files overlap. Useful for finding which other cameras 
 50    might have seen an event seen by the first camera. 
 51
 52    Arguments:  
 53        kmlfile1:       [str] full path to first KML file  
 54        kmlfile2:       [str] full path to second KML file  
 55
 56    Returns:  
 57        True or False
 58    """
 59    _,p1 = _munchKML(kmfile1)
 60    _,p2 = _munchKML(kmfile2)
 61    return p1.intersects(p2)
 62
 63
 64def getOverlapWith(srcfolder, kmlpattern='*-25km.kml', refcam='UK0006'):
 65    """
 66    Check for overlap between the named camera, and every KML file in a folder, at the pattern altitude  
 67
 68    Arguments:  
 69        srcfolder:  [str] path to folder containing KML files to test.   
 70        kmlpattern: [str] kml pattern to match. Default "*-25km.kml"  
 71        refcam:     [str] Cameraid to check against. Its KML must be in srcfolder  
 72     
 73    Returns:  
 74        list of camera IDs that overlap with the target  
 75    """
 76    kmllist = glob.glob1(srcfolder, kmlpattern)
 77    currmatches=[]
 78    refkml = f'{refcam}{kmlpattern[1:]}'
 79    currmatches.append(refcam[:6])
 80    print('checking ', refkml)
 81    for testkml in kmllist:
 82        if testkml != refkml:
 83            testcam,_ = os.path.splitext(testkml)
 84            if checkKMLOverlap(os.path.join(srcfolder, refkml), os.path.join(srcfolder, testkml)) is True:
 85                currmatches.append(testcam[:6])
 86    return currmatches
 87
 88
 89
 90def getOverlappingCameras(srcfolder, kmlpattern='*-25km.kml'):
 91    """
 92    Check for all overlaps in the folder at the pattern altitude. Returns a massive 2d array  
 93
 94    Arguments:  
 95        srcfolder:  [str] path to folder containing KML files to test.   
 96        kmlpattern: [str] kml pattern to match. Default "*-25km.kml"  
 97
 98    Returns:  
 99        list of lists of groups of overlaping IDs 
100     
101    """
102    kmllist = glob.glob1(srcfolder, kmlpattern)
103    kmllist2 = kmllist
104    matches = []
105
106    for refkml in kmllist:
107        currmatches=[]
108        refcam,_ = os.path.splitext(refkml)
109        currmatches.append(refcam[:6])
110        for testkml in kmllist2:
111            if testkml != refkml:
112                testcam,_ = os.path.splitext(testkml)
113                if checkKMLOverlap(os.path.join(srcfolder, refkml), os.path.join(srcfolder, testkml)) is True:
114                    currmatches.append(testcam[:6])
115        matches.append(currmatches)
116    return matches
def pointInsideFov(latDegs, lngDegs, kmlFilename):
29def pointInsideFov(latDegs,lngDegs, kmlFilename):
30    """
31    Test if a point is inside the field of view of a KML file. Useful for testing which 
32    cameras might have seen an event at a known location.  
33
34    Arguments:  
35        latDegs:        [degrees] latitude of the point  
36        lngDegs:        [degrees] latitude of the point  
37        kmlFileName:    [str] full path to the KML file to test  
38
39    Returns:  
40        True or False  
41    """
42
43    c1, p1 = _munchKML(kmlFilename)
44    pt = Point(latDegs, lngDegs)
45    return p1.contains(pt)

Test if a point is inside the field of view of a KML file. Useful for testing which cameras might have seen an event at a known location.

Arguments:
latDegs: [degrees] latitude of the point
lngDegs: [degrees] latitude of the point
kmlFileName: [str] full path to the KML file to test

Returns:
True or False

def checkKMLOverlap(kmfile1, kmfile2):
48def checkKMLOverlap(kmfile1, kmfile2):
49    """
50    Test if two KML files overlap. Useful for finding which other cameras 
51    might have seen an event seen by the first camera. 
52
53    Arguments:  
54        kmlfile1:       [str] full path to first KML file  
55        kmlfile2:       [str] full path to second KML file  
56
57    Returns:  
58        True or False
59    """
60    _,p1 = _munchKML(kmfile1)
61    _,p2 = _munchKML(kmfile2)
62    return p1.intersects(p2)

Test if two KML files overlap. Useful for finding which other cameras might have seen an event seen by the first camera.

Arguments:
kmlfile1: [str] full path to first KML file
kmlfile2: [str] full path to second KML file

Returns:
True or False

def getOverlapWith(srcfolder, kmlpattern='*-25km.kml', refcam='UK0006'):
65def getOverlapWith(srcfolder, kmlpattern='*-25km.kml', refcam='UK0006'):
66    """
67    Check for overlap between the named camera, and every KML file in a folder, at the pattern altitude  
68
69    Arguments:  
70        srcfolder:  [str] path to folder containing KML files to test.   
71        kmlpattern: [str] kml pattern to match. Default "*-25km.kml"  
72        refcam:     [str] Cameraid to check against. Its KML must be in srcfolder  
73     
74    Returns:  
75        list of camera IDs that overlap with the target  
76    """
77    kmllist = glob.glob1(srcfolder, kmlpattern)
78    currmatches=[]
79    refkml = f'{refcam}{kmlpattern[1:]}'
80    currmatches.append(refcam[:6])
81    print('checking ', refkml)
82    for testkml in kmllist:
83        if testkml != refkml:
84            testcam,_ = os.path.splitext(testkml)
85            if checkKMLOverlap(os.path.join(srcfolder, refkml), os.path.join(srcfolder, testkml)) is True:
86                currmatches.append(testcam[:6])
87    return currmatches

Check for overlap between the named camera, and every KML file in a folder, at the pattern altitude

Arguments:
srcfolder: [str] path to folder containing KML files to test.
kmlpattern: [str] kml pattern to match. Default "*-25km.kml"
refcam: [str] Cameraid to check against. Its KML must be in srcfolder

Returns:
list of camera IDs that overlap with the target

def getOverlappingCameras(srcfolder, kmlpattern='*-25km.kml'):
 91def getOverlappingCameras(srcfolder, kmlpattern='*-25km.kml'):
 92    """
 93    Check for all overlaps in the folder at the pattern altitude. Returns a massive 2d array  
 94
 95    Arguments:  
 96        srcfolder:  [str] path to folder containing KML files to test.   
 97        kmlpattern: [str] kml pattern to match. Default "*-25km.kml"  
 98
 99    Returns:  
100        list of lists of groups of overlaping IDs 
101     
102    """
103    kmllist = glob.glob1(srcfolder, kmlpattern)
104    kmllist2 = kmllist
105    matches = []
106
107    for refkml in kmllist:
108        currmatches=[]
109        refcam,_ = os.path.splitext(refkml)
110        currmatches.append(refcam[:6])
111        for testkml in kmllist2:
112            if testkml != refkml:
113                testcam,_ = os.path.splitext(testkml)
114                if checkKMLOverlap(os.path.join(srcfolder, refkml), os.path.join(srcfolder, testkml)) is True:
115                    currmatches.append(testcam[:6])
116        matches.append(currmatches)
117    return matches

Check for all overlaps in the folder at the pattern altitude. Returns a massive 2d array

Arguments:
srcfolder: [str] path to folder containing KML files to test.
kmlpattern: [str] kml pattern to match. Default "*-25km.kml"

Returns:
list of lists of groups of overlaping IDs