Exemplo n.º 1
0
 def test_BeachBallOutputFormats(self):
     """
     Tests various output formats.
     """
     fm = [115, 35, 50]
     # PDF
     data = Beachball(fm, format='pdf')
     self.assertEqual(data[0:4], b"%PDF")
     # as file
     # create and compare image
     with NamedTemporaryFile(suffix='.pdf') as tf:
         Beachball(fm, format='pdf', outfile=tf.name)
     # PS
     data = Beachball(fm, format='ps')
     self.assertEqual(data[0:4], b"%!PS")
     # as file
     with NamedTemporaryFile(suffix='.ps') as tf:
         Beachball(fm, format='ps', outfile=tf.name)
     # PNG
     data = Beachball(fm, format='png')
     self.assertEqual(data[1:4], b"PNG")
     # as file
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(fm, format='png', outfile=tf.name)
     # SVG
     data = Beachball(fm, format='svg')
     self.assertEqual(data[0:5], b"<?xml")
     # as file
     with NamedTemporaryFile(suffix='.svg') as tf:
         Beachball(fm, format='svg', outfile=tf.name)
Exemplo n.º 2
0
 def test_BeachBallOutputFormats(self):
     """
     Tests various output formats.
     """
     fm = [115, 35, 50]
     # PDF
     data = Beachball(fm, format='pdf')
     self.assertEqual(data[0:4], "%PDF")
     # as file
     Beachball(fm, format='pdf', outfile=os.path.join(self.path, 'bb.pdf'))
     # PS
     data = Beachball(fm, format='ps')
     self.assertEqual(data[0:4], "%!PS")
     # as file
     Beachball(fm, format='ps', outfile=os.path.join(self.path, 'bb.ps'))
     # PNG
     data = Beachball(fm, format='png')
     self.assertEqual(data[1:4], "PNG")
     # as file
     Beachball(fm, format='png', outfile=os.path.join(self.path, 'bb.png'))
     # SVG
     data = Beachball(fm, format='svg')
     self.assertEqual(data[0:5], "<?xml")
     # as file
     Beachball(fm, format='svg', outfile=os.path.join(self.path, 'bb.svg'))
    def draw(self):

        csvfile = self.fichierSrc.get()
        saveDir = self.repSave.get()

        fichier = open(csvfile)
        fichercsv = csv.reader(fichier, delimiter=' ')

        nb_meca = 0
        for var in fichercsv:
            nb_meca = nb_meca + 1
        nb_meca = nb_meca - 1
        fichier.close()

        fichier = open(csvfile)
        fichercsv = csv.reader(fichier, delimiter=' ')

        i = 1

        for var in fichercsv:
            if i > 1:
                bb = Beachball([float(var[1]),
                                float(var[2]),
                                float(var[3])],
                               size=1,
                               linewidth=2,
                               facecolor='r',
                               outfile=saveDir + '/' + str(var[0]) + ".svg")
                plt.close("all")
            i = i + 1
            self.progress(str(i) + '/' + str(nb_meca))

        self.progress("Done")
Exemplo n.º 4
0
 def test_Beachball(self):
     """
     Create beachball examples in tests/output directory.
     """
     reltol = 1
     if MATPLOTLIB_VERSION < [1, 3, 0]:
         reltol = 60
     # http://en.wikipedia.org/wiki/File:USGS_sumatra_mts.gif
     data = [[0.91, -0.89, -0.02, 1.78, -1.55, 0.47],
             [274, 13, 55],
             [130, 79, 98],
             [264.98, 45.00, -159.99],
             [160.55, 76.00, -46.78],
             [1.45, -6.60, 5.14, -2.67, -3.16, 1.36],
             [235, 80, 35],
             [138, 56, 168],
             # Explosion
             [1, 1, 1, 0, 0, 0],
             # Implosion
             [-1, -1, -1, 0, 0, 0],
             # CLVD - Compensate Linear Vector Dipole
             [1, -2, 1, 0, 0, 0],
             # Double Couple
             [1, -1, 0, 0, 0, 0],
             # Lars
             [1, -1, 0, 0, 0, -1],
             # http://wwweic.eri.u-tokyo.ac.jp/yuji/Aki-nada/
             [179, 55, -78],
             [10, 42.5, 90],
             [10, 42.5, 92],
             # http://wwweic.eri.u-tokyo.ac.jp/yuji/tottori/
             [150, 87, 1],
             # http://iisee.kenken.go.jp/staff/thara/2004/09/20040905_1/
             # 2nd.html
             [0.99, -2.00, 1.01, 0.92, 0.48, 0.15],
             # http://iisee.kenken.go.jp/staff/thara/2004/09/20040905_0/
             # 1st.html
             [5.24, -6.77, 1.53, 0.81, 1.49, -0.05],
             # http://iisee.kenken.go.jp/staff/thara/miyagi.htm
             [16.578, -7.987, -8.592, -5.515, -29.732, 7.517],
             # http://iisee.kenken.go.jp/staff/thara/20050613/chile.html
             [-2.39, 1.04, 1.35, 0.57, -2.94, -0.94],
             ]
     filenames = ['bb_sumatra_mt.png', 'bb_sumatra_np1.png',
                  'bb_sumatra_np2.png', 'bb_19950128_np1.png',
                  'bb_19950128_np2.png', 'bb_20090102_mt.png',
                  'bb_20090102_np1.png', 'bb-20090102-np2.png',
                  'bb_explosion.png', 'bb_implosion.png', 'bb_clvd.png',
                  'bb_double_couple.png', 'bb_lars.png', 'bb_geiyo_np1.png',
                  'bb_honshu_np1.png', 'bb_honshu_np2.png',
                  'bb_tottori_np1.png', 'bb_20040905_1_mt.png',
                  'bb_20040905_0_mt.png', 'bb_miyagi_mt.png',
                  'bb_chile_mt.png',
                  ]
     for data_, filename in zip(data, filenames):
         with ImageComparison(self.path, filename, reltol=reltol) as ic:
             Beachball(data_, outfile=ic.name)
Exemplo n.º 5
0
def draw_beachballs():
    data = parse_data()
    for event in list(data):
        if event[5] < 70:
            face_color = '#ff0000'
        elif event[5] > 300:
            face_color = '#0000ff'
        else:
            face_color = '#ffff00'

        try:
            Beachball(event[3],
                      facecolor=face_color,
                      width=100,
                      outfile='static/beachballs4/' + event[0] + '.png')
        except:  # IndexError:
            print "Error for event " + event[0]
            Beachball(event[4],
                      facecolor=face_color,
                      width=100,
                      outfile='static/beachballs4/' + event[0] + '.png')
Exemplo n.º 6
0
def beachball(data):
    """function to draw beachball, slightly different from Qfocal"""
    strike, dip, rake = data['str1'], data['dip1'], data['rake1']
    #event = np.arange(0, len(data),1)
    for j in range(len(strike)):
        width = (data['mw'][j] * 100)  #/2
        fm_SDR = [strike[j], dip[j], rake[j]]
        #fm_NM = [data['mxx'][j], data['mxy'][j], data['mxz'][j],
        #         data['myy'][j], data['myz'][j], data['mzz'][j]]
        Beachball(fm_SDR,
                  outfile=beachout + str(data['event_id'][j]),
                  facecolor=Qfocal.color_by_depth_interval(data['CD'][j]),
                  width=width,
                  edgecolor='black')
        plt.close()
Exemplo n.º 7
0
    def produceImage(self,
                     strike=None,
                     dip=None,
                     rake=None,
                     mrr=None,
                     mtt=None,
                     mpp=None,
                     mrt=None,
                     mtp=None,
                     mrp=None):

        mt = []
        filename = None
        if (strike != None and dip != None and rake != None):
            mt = [strike, dip, rake]
            filename = base64.urlsafe_b64encode(
                str(strike) + "-" + str(dip) + "-" + str(rake)) + ".png"

        else:
            if (mrr != None and mtt != None and mpp != None and mrt != None
                    and mrp != None and mtp != None):
                mt = [mrr, mtt, mpp, mrt, mrp, mtp]
                filename = base64.urlsafe_b64encode(
                    str(mrr) + "-" + str(mtt) + "-" + str(mpp) + "-" +
                    str(mrt) + "-" + str(mrp) + "-" + str(mtp)) + ".png"

        outfile = self.__imagespath__ + filename

        if os.path.isfile(outfile) != True:
            Beachball(mt,
                      size=100,
                      linewidth=2,
                      facecolor='r',
                      outfile=outfile)

        return outfile
Exemplo n.º 8
0
 def plot(self):
     from obspy.imaging.beachball import Beachball
     Beachball([self.tensor[0,0],self.tensor[1,1],self.tensor[2,2],self.tensor[0,1],self.tensor[0,2],self.tensor[1,2]])
Exemplo n.º 9
0
from obspy.imaging.beachball import Beachball

mt = [0.91, -0.89, -0.02, 1.78, -1.55, 0.47]
Beachball(mt, size=200, linewidth=2, facecolor='b')

mt2 = [150, 87, 1]
Beachball(mt2, size=200, linewidth=2, facecolor='r')

mt3 = [-2.39, 1.04, 1.35, 0.57, -2.94, -0.94]
Beachball(mt3, size=200, linewidth=2, facecolor='g')
Exemplo n.º 10
0
 def test_Beachball(self):
     """
     Create beachball examples in tests/output directory.
     """
     # http://en.wikipedia.org/wiki/File:USGS_sumatra_mts.gif
     mt = [0.91, -0.89, -0.02, 1.78, -1.55, 0.47]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(mt, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_sumatra_mt.png')
         compare_images(tf.name, expected_image, 0.001)
     np1 = [274, 13, 55]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(np1, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_sumatra_np1.png')
         compare_images(tf.name, expected_image, 0.001)
     np2 = [130, 79, 98]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(np2, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_sumatra_np2.png')
         compare_images(tf.name, expected_image, 0.001)
     #
     np1 = [264.98, 45.00, -159.99]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(np1, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_19950128_np1.png')
         compare_images(tf.name, expected_image, 0.001)
     np2 = [160.55, 76.00, -46.78]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(np2, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_19950128_np2.png')
         compare_images(tf.name, expected_image, 0.001)
     #
     mt = [1.45, -6.60, 5.14, -2.67, -3.16, 1.36]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(mt, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_20090102_mt.png')
         compare_images(tf.name, expected_image, 0.001)
     np1 = [235, 80, 35]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(np1, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_20090102_np1.png')
         compare_images(tf.name, expected_image, 0.001)
     np2 = [138, 56, 168]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(np2, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb-20090102-np2.png')
         compare_images(tf.name, expected_image, 0.001)
     # Explosion
     mt = [1, 1, 1, 0, 0, 0]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(mt, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_explosion.png')
         compare_images(tf.name, expected_image, 0.001)
     # Implosion
     mt = [-1, -1, -1, 0, 0, 0]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(mt, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_implosion.png')
         compare_images(tf.name, expected_image, 0.001)
     # CLVD - Compensate Linear Vector Dipole
     mt = [1, -2, 1, 0, 0, 0]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(mt, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_clvd.png')
         compare_images(tf.name, expected_image, 0.001)
     # Double Couple
     mt = [1, -1, 0, 0, 0, 0]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(mt, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_double_couple.png')
         compare_images(tf.name, expected_image, 0.001)
     # Lars
     mt = [1, -1, 0, 0, 0, -1]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(mt, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_lars.png')
         compare_images(tf.name, expected_image, 0.001)
     # http://wwweic.eri.u-tokyo.ac.jp/yuji/Aki-nada/
     np1 = [179, 55, -78]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(np1, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_geiyo_np1.png')
         compare_images(tf.name, expected_image, 0.001)
     #
     np1 = [10, 42.5, 90]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(np1, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_honshu_np1.png')
         compare_images(tf.name, expected_image, 0.001)
     np2 = [10, 42.5, 92]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(np2, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_honshu_np2.png')
         compare_images(tf.name, expected_image, 0.001)
     # http://wwweic.eri.u-tokyo.ac.jp/yuji/tottori/
     np1 = [150, 87, 1]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(np1, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_tottori_np1.png')
         compare_images(tf.name, expected_image, 0.001)
     # http://iisee.kenken.go.jp/staff/thara/2004/09/20040905_1/2nd.html
     mt = [0.99, -2.00, 1.01, 0.92, 0.48, 0.15]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(mt, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_20040905_1_mt.png')
         compare_images(tf.name, expected_image, 0.001)
     # http://iisee.kenken.go.jp/staff/thara/2004/09/20040905_0/1st.html
     mt = [5.24, -6.77, 1.53, 0.81, 1.49, -0.05]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(mt, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_20040905_0_mt.png')
         compare_images(tf.name, expected_image, 0.001)
     # http://iisee.kenken.go.jp/staff/thara/miyagi.htm
     mt = [16.578, -7.987, -8.592, -5.515, -29.732, 7.517]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(mt, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_miyagi_mt.png')
         compare_images(tf.name, expected_image, 0.001)
     # http://iisee.kenken.go.jp/staff/thara/20050613/chile.html
     mt = [-2.39, 1.04, 1.35, 0.57, -2.94, -0.94]
     with NamedTemporaryFile(suffix='.png') as tf:
         Beachball(mt, outfile=tf.name)
         expected_image = os.path.join(self.path, 'bb_chile_mt.png')
         compare_images(tf.name, expected_image, 0.001)
Exemplo n.º 11
0
from obspy.imaging.beachball import Beachball
np1 = [285, 40, -45]
Beachball(np1, facecolor='r') 
Exemplo n.º 12
0
def create_ev_sta_kml(input_dics, events):
    """
    create event/station/ray in KML format readable by Google-Earth
    :param input_dics:
    :param events:
    :return:
    """
    try:
        from pykml.factory import KML_ElementMaker as KML
        from lxml import etree
    except:
        sys.exit('[ERROR] pykml should be installed first!')

    if not os.path.isdir('kml_dir'):
        os.mkdir('kml_dir')
    else:
        print('[INFO] kml_dir already exists!')

    # create a document element with multiple label style
    kmlobj = KML.kml(KML.Document())
    counter = 0
    for ei in range(len(events)):
        print(events[ei]['event_id'])
        counter += 1

        ev_date = '%04i/%02i/%02i-%02i:%02i:%02i' \
                  % (events[ei]['datetime'].year,
                     events[ei]['datetime'].month,
                     events[ei]['datetime'].day,
                     events[ei]['datetime'].hour,
                     events[ei]['datetime'].minute,
                     events[ei]['datetime'].second
                     )

        if input_dics['plot_focal']:
            try:
                focmecs = [float(events[ei]['focal_mechanism'][0]),
                           float(events[ei]['focal_mechanism'][1]),
                           float(events[ei]['focal_mechanism'][2]),
                           float(events[ei]['focal_mechanism'][3]),
                           float(events[ei]['focal_mechanism'][4]),
                           float(events[ei]['focal_mechanism'][5])]
            except:
                print("WARNING: 'focal_mechanism' does not exist!")
                focmecs = [1, 1, 1, 0, 0, 0]
        else:
            focmecs = [1, 1, 1, 0, 0, 0]

        if 0 <= events[ei]['depth'] < 70:
            event_color = 'red'
        elif 70 <= events[ei]['depth'] < 300:
            event_color = 'green'
        else:
            event_color = 'blue'

        try:
            Beachball(focmecs,
                      outfile=os.path.join(
                          'kml_dir', events[ei]['event_id'] + '.png'),
                      facecolor=event_color,
                      edgecolor=event_color)
        except Exception as error:
            print(error)
            print(focmecs)
            continue
        plt.close()
        plt.clf()

        if input_dics['plot_ev'] or input_dics['plot_ray']:
            kmlobj.Document.append(
                KML.Style(
                    KML.IconStyle(
                        KML.Icon(KML.href(os.path.join(
                            events[ei]['event_id'] + '.png')),
                        ),
                        KML.scale(events[ei]['magnitude']/2.),
                        KML.heading(0.0),
                    ),
                    id='beach_ball_%i' % counter
                ),
            )

            kmlobj.Document.append(
                KML.Placemark(
                    KML.name(events[ei]['event_id']),
                    KML.ExtendedData(
                        KML.Data(
                            KML.value('%s' % events[ei]['event_id']),
                            name='event_id'
                        ),
                        KML.Data(
                            KML.value('%s' % events[ei]['magnitude']),
                            name='magnitude'
                        ),
                        KML.Data(
                            KML.value('%s' % ev_date),
                            name='datetime'
                        ),
                        KML.Data(
                            KML.value('%s' % events[ei]['depth']),
                            name='depth'
                        ),
                        KML.Data(
                            KML.value('%s' % events[ei]['latitude']),
                            name='latitude'
                        ),
                        KML.Data(
                            KML.value('%s' % events[ei]['longitude']),
                            name='longitude'
                        ),
                    ),
                    KML.styleUrl('#beach_ball_%i' % counter),
                    # KML.Point(KML.coordinates(events[ei]['longitude'], ',',
                    #                           events[ei]['latitude'], ',',
                    #                           700000 -
                    #                           abs(events[ei]['depth']*1000)),
                    #           KML.altitudeMode('absolute')
                    #           ),
                    KML.Point(KML.coordinates(events[ei]['longitude'], ',',
                                              events[ei]['latitude'], ',',
                                              0.),
                              KML.altitudeMode('absolute')
                              ),
                ),
            )

        if input_dics['plot_sta'] or input_dics['plot_ray']:
            target_path = locate(input_dics['datapath'],
                                 events[ei]['event_id'])
            if len(target_path) < 1:
                continue
            if len(target_path) > 1:
                print("[LOCAL] more than one path was found for the event:")
                print(target_path)
                print("[INFO] use the first one:")
                target_path = target_path[0]
                print(target_path)
            else:
                print("[LOCAL] Path:")
                target_path = target_path[0]
                print(target_path)

            update_sta_ev_file(target_path, events[ei])
            sta_ev_arr = np.loadtxt(os.path.join(target_path,
                                                 'info', 'station_event'),
                                    delimiter=',', dtype=bytes, ndmin=2).astype(np.str)
            sta_ev_arr = sta_ev_arr.astype(np.object)
            del_index = []
            for sti in range(len(sta_ev_arr)):

                if not plot_filter_station(input_dics, sta_ev_arr[sti]):
                    del_index.append(sti)

                dist, azi, bazi = gps2DistAzimuth(events[ei]['latitude'],
                                                  events[ei]['longitude'],
                                                  float(sta_ev_arr[sti, 4]),
                                                  float(sta_ev_arr[sti, 5]))

                epi_dist = dist/111.194/1000.
                if input_dics['min_azi'] or input_dics['max_azi'] or \
                        input_dics['min_epi'] or input_dics['max_epi']:
                    if input_dics['min_epi']:
                        if epi_dist < input_dics['min_epi']:
                            del_index.append(sti)
                    if input_dics['max_epi']:
                        if epi_dist > input_dics['max_epi']:
                            del_index.append(sti)
                    if input_dics['min_azi']:
                        if azi < input_dics['min_azi']:
                            del_index.append(sti)
                    if input_dics['max_azi']:
                        if azi > input_dics['max_azi']:
                            del_index.append(sti)

            del_index = list(set(del_index))
            del_index.sort(reverse=True)
            for di in del_index:
                sta_ev_arr = np.delete(sta_ev_arr, (di), axis=0)

            kmlobj.Document.append(
                KML.Style(
                    KML.IconStyle(
                        KML.scale(2.5),
                        KML.heading(0.0),
                    ),
                    id='station'
                ),
            )
            kmlobj.Document.append(
                KML.Style(
                    KML.LineStyle(
                        KML.width(1.0),
                        # KML.color('ff33ccff'),
                        KML.color('2333ccff'),
                    ),
                    id='great_circle_distance'
                ),
            )
            for sti in sta_ev_arr:
                dist, azi, bazi = gps2DistAzimuth(events[ei]['latitude'],
                                                  events[ei]['longitude'],
                                                  float(sti[4]),
                                                  float(sti[5]))
                epi_dist = dist/111.194/1000.
                sta_id = '%s.%s.%s.%s' % (sti[0], sti[1], sti[2], sti[3])
                kmlobj.Document.append(
                    KML.Placemark(
                        KML.name(sta_id),
                        KML.ExtendedData(
                            KML.Data(
                                KML.value('%s' % sta_id),
                                name='StationID'
                            ),
                            KML.Data(
                                KML.value('%s' % epi_dist),
                                name='Distance'
                            ),
                            KML.Data(
                                KML.value('%s' % sti[6]),
                                name='Elevation'
                            ),
                            KML.Data(
                                KML.value('%s' % sti[7]),
                                name='Depth'
                            ),
                            KML.Data(
                                KML.value('%s' % bazi),
                                name='Back-Azimuth'
                            ),
                            KML.Data(
                                KML.value('%s' % azi),
                                name='Azimuth'
                            ),
                            KML.Data(
                                KML.value('%s' % events[ei]['event_id']),
                                name='EventID'
                            ),
                            KML.Data(
                                KML.value('%s' % sti[8]),
                                name='Source'
                            ),
                        ),
                        KML.styleUrl('station'),
                        KML.Point(KML.coordinates(
                            float(sti[5]), ',', float(sti[4]))
                        ),
                    ),
                )
                if input_dics['plot_ray']:
                    kmlobj.Document.append(
                        KML.Placemark(
                            KML.name(sta_id),
                            KML.ExtendedData(
                                KML.Data(
                                    KML.value('%s' % sta_id),
                                    name='StationID'
                                ),
                            ),
                            KML.styleUrl('great_circle_distance'),
                            KML.LineString(KML.coordinates(
                                '%s,%s,0\n'
                                '%s,%s,0' % (float(sti[5]),
                                             float(sti[4]),
                                             events[ei]['longitude'],
                                             events[ei]['latitude'])),
                                KML.tessellate(1)),
                        ),
                    )
    kml_outfile = file(os.path.join(
        'kml_dir',
        'kml_output.kml'), 'w')
    kml_outfile.write(etree.tostring(kmlobj, pretty_print=True))
    sys.exit('[INFO] KML file is stored in ./kml_dir!')