我有一个业余网站,为骑自行车的人提供赛道。
该网站的目标之一是沿着 gpx 轨道提供 POI(兴趣点)。
我有数百个数据库,每个数据库都有数千条数据。
目前,我创建了一个脚本,用于搜索距特定 gpx 点 1 公里范围内的 POI,将结果添加到文件中,对它们进行排序,删除双打。
它可以工作,但由于我计划将每个轨道添加到我的网站,因此我需要重复该过程 5K 次,这导致操作非常慢。
这是我安排的代码
#!/bin/sh
POI_FILES="poi_files.list"
find Db_Poi_Base/ -type f >"${POI_FILES}"
awk -F, '$1>12.295 \
&& $1<12.579 \
&& $2>46.186 \
&& $2<46.289 {
print $0 ",",FILENAME
}' "${POI_FILES}" > "poi_base.txt"
# Looping from this point to end of script
awk -F, '$1>13.136357 \
&& $1<13.156357 \
&& $2>45.679686 \
&& $2<45.699686 {
print $0 ",",FILENAME
}' "${POI_FILES}" > "poi_base1.txt"
if [ -s "poi_base.txt" && -s "poi_base1.txt" ]
then
cat poi_base.txt poi_base1.txt |
awk '!seen[$0]++' > poi_base2.txt
fi
if [ -s "poi_base2.txt" ]
then
sed 's/\r//' poi_base2.txt > poi_base.txt
fi
首先AWK在识别的文件内部进行搜索,将结果与特定参数相匹配,然后添加逗号和特定数据库的文件名,在其中找到数据;最后将所有内容保存到txt文件中。
第二个 AWK 执行与第一个 AWK 相同的操作,只是 txt 文件名发生了更改。
之后,两个数据文件将被合并并传递给 AWK 以删除双打并创建第三个文件。
最后,将检查数据以删除可能存在于同一行中的^M字符(回车符),将结果文件命名为与第一行相同;这让我只用 3 个文件循环。
从第二个 AWK 开始,将循环更改参数,直到分析点结束。
原始 gpx 文件具有以下结构
Index Lat Lon
0 45.689686 N 45° 41.381160' N 13.146357 E 13° 8.781420' E
1 45.689657 N 45° 41.379420' N 13.146311 E 13° 8.778660' E
Poi 的 Dbase 文件具有以下结构(用逗号分隔的三列 csv 文件)
9.107150,39.219720,Moto Race Srl Accessori Abbigliament Cagliari>39070651423
9.141090,39.236280,Il Centauro Dei Fratelli Sanna Cocco Cagliari>39070492692
9.176310,39.241830,Planet Motors Aprilia Conce Quartu Sant'elena>39070881179
在生成脚本时,我将在开源电子表格上导入数据并使用一些公式对其进行管理。 例如,将+0.01和-0,01值(1公里)输入Lat和Lon,以获得搜索范围...
由于一切正常,即使速度慢得令人难以置信,我想知道是否有办法加快进程。 我也尝试过使用数组,如下所示
IFS=$'\n'&&i=5491&&readarray -t my_array1 < <(find Db_Poi_Base/ -type f -exec awk -F, '$1>13.136357 && $1<13.156357 && $2>45.679686 && $2<45.699686 {print $0 ",",FILENAME}' {} \;)&&echo durata stimata: 91,5 minuti&&echo riga: $i ;((i=i-1))
readarray -t my_array2 < <(find Db_Poi_Base/ -type f -exec awk -F, '$1>12.946311 && $1<13.346311 && $2>45.489657 && $2<45.889657 {print $0 ",",FILENAME}' {} \;)&& my_array1+=(${my_array2[@]})&&echo riga: $i ;((i=i-1))
第一行部分(IFS=$' '&&i=5491&&) 用于避免回车并设置倒计时变量以表明脚本正在进行中。 每行的第二部分 (&&echo riga: $i ;((i=i-1)) 在回显行号后减少变量。
数组解决方案仅部分有效,因为它没有排序和删除双精度数。
预期输出如下
13.143540,45.688900,UD Lignano Sabbiadoro -(H R) Desiree>39043171415, Db_Poi_Base/Ristoranti_Senza_Glutine/Ristoranti_Senza_Glutine.csv
13.140550,45.688220,T La Conchiglia Lignano Sabbiadoro UD>39043173861, Db_Poi_Base/Tabacchi/Tabacchi.csv
13.142680,45.689260,T Sebastianis Laura Lignano Sabbiadoro UD>390431720656, Db_Poi_Base/Tabacchi/Tabacchi.csv
13.144810,45.691160,T Di Bella Salvatore Lignano Sabbiadoro UD>39043173820, Db_Poi_Base/Tabacchi/Tabacchi.csv
13.143750,45.691250,T Gusso Luigi Lignano Sabbiadoro UD>39043170187, Db_Poi_Base/Tabacchi/Tabacchi.csv
13.146660,45.691940,T Zamolo Metullio Lignano Sabbiadoro UD>39043170777, Db_Poi_Base/Tabacchi/Tabacchi.csv
13.148370,45.693080,T Passilongo Mario Lignano Sabbiadoro UD>39043171922, Db_Poi_Base/Tabacchi/Tabacchi.csv
这些是我的首要问题。
作为次要的好奇心,但实际上并不是一个很好的好奇心,就像电子表格一样,一切都足够快,就是直接在脚本中实现 gpx 文件,例如使用 do while 循环,从外部 gpx 文件读取每一行,并将亲属列的数据放入命令序列中。
感谢您的任何建议。
由于两个文件的格式相同,您可以通过简单地执行以下操作来删除重复项:
cat poi_base.txt poi_base1.txt | sort | uniq |
对于项目的总体概念,我建议为每个兴趣点(POI)分配一个唯一的ID,如下所示:
poi_00903|9.107150,39.219720,Moto Race Srl Accessori Abbigliament Cagliari>39070651423
poi_00904|9.141090,39.236280,Il Centauro Dei Fratelli Sanna Cocco Cagliari>39070492692
poi_00905|9.176310,39.241830,Planet Motors Aprilia Conce Quartu Sant'elena>39070881179
该 ID 可能与自行车/步行道的 ID 相关,也可能无关。
执行一项大型任务,识别每个路径坐标检查点指定范围内 POI 的 ID,并将这些任务在修改后的 GPX 文件 (*.gpx_poi) 中的每个项目行的附加字段中作为附加项目列出。
例如,如果原始 GPX 文件名为
Montessori_053.gpx
一条位置线是
37 45.689657 N 45° 41.379420' N 13.146311 E 13° 8.778660' E
您可以给相关的 POI 文件命名
Montessori_053.gpx_poi
相关行可以格式化(带坐标)为
37 45.689657 N 45° 41.379420' N 13.146311 E 13° 8.778660' E ,poi_00903 poi_00904 poi__00907,poi_00792 poi_00795,poi_0348 poi_01009 poi_01201
或没有坐标
37,poi_00903 poi_00904 poi__00907,poi_00792 poi_00795,poi_0348 poi_01009 poi_01201
其中第 1、2、3 组分别是 1 公里、3 公里和 10 公里范围内的 POI。
拥有 POI“预分析”和预编译将使应用程序的响应速度更快,因为您已将查找工作量减少到简单的路径索引匹配以获取相关“POI ID”的位置需要提取并显示。
您可能还想创建一个“行程规划器”,在其中提供对沿给定路径识别的所有 POI 的唯一引用,以及复选框。然后,用户可以保存该原始+检查列表以供以后参考。 当用户为他们的旅行选择“开始徒步旅行”时,它会在这些路线上最近的点突出显示“选中的”POI,并带有“pin flag label”。 如果用户改变了他们可能想要访问的内容或访问时间,您可能需要提供“重新访问”原始列表的选项来更改复选标记选择。 只是一些想法。 你的主意非常好。 祝您的项目顺利!
首先,我使用以下命令创建一个文件来减少总数据,仅提取特定范围内的数据(最大和最小纬度和经度)。
find Db_Poi_Base/ -type f -exec awk -F, '$1>13.011409 && $1<13.783151 && $2>45.641559 && $2<46.10597 {print $0 ",",FILENAME}' {} > "poi_base-test.txt" \;
比我更改了上面使用的命令的第一部分,设置为在特定文件内搜索:
find poi_base-test.txt -type f -exec awk -F, '$1>13.136357 && $1<13.156357 && $2>45.679686 && $2<45.699686 {print $0}' {} > "poi_base.txt" \;&&i=5491&&echo Termina tra: $t minuti&&echo riga: $i ;((i=i-1));((t=i/45))
结果是正确的,现在已经足够快满足我的需求了