ich würde die city.list in ein file of TCity umwandeln.
Das ist nur selten nötig und damit ist sie leichter handhabbar.
Aber die wollen jetzt einen persönlichen "API key" , einen öffentlichen API key gibt es wohl nicht.
Ich habe jetzt ein Datei mit records gemacht.
Code: Alles auswählen
program JsonTest;
uses
SysUtils,
Classes,
strutils;
const
ZeilenProJSONDatum = 9;
cInName = 'city.list.json';
cOutName = 'City.dat';
type
TCity = record
ctLat, ctLon: double;
ctId: longword;
ctCty: string[3];
ctName: string[79];
end;
var
T1, T0: int64;
POIs : array of TCity;
procedure Split(const s:string;
var POI:tCity);
//-> {"id":707860,"name":"Hurzuf","country":"UA","coord":{"lon":34.283333,"lat":44.549999}},
var
StartIdx,EndIdx: NativeInt;
Begin
with POI do
Begin
StartIdx:= Pos(':',s)+1;
EndIdx := PosEx(',', s,StartIdx);
ctId:= StrToInt(copy(s,StartIdx,EndIdx-StartIdx));
StartIdx:= PosEx(':',s,EndIdx+7)+2;
EndIdx := PosEx(',', s,StartIdx)-1;
ctname:= copy(s,StartIdx,EndIdx-StartIdx);
StartIdx:= PosEx(':',s,EndIdx+11)+2;
EndIdx := PosEx(',', s,StartIdx)-1;
ctCty := copy(s,StartIdx,EndIdx-StartIdx);
StartIdx:= PosEx(':',s,EndIdx+11)+1;
EndIdx := PosEx(',', s,StartIdx);
ctLon := StrToFloat(copy(s,StartIdx,EndIdx-StartIdx));
StartIdx:= PosEx(':',s,EndIdx+5)+1;
EndIdx := PosEx('}', s,StartIdx);
ctLat := StrToFloat(copy(s,StartIdx,EndIdx-StartIdx));
end;
end;
procedure removeSpaceAfter(var s: string);
//': '-> ':'
var
i, j: NativeInt;
begin
j := 1;
i := 1;
while i <= length(s) do
begin
s[j] := s[i];
if s[i] = ':' then
Inc(i);
Inc(j);
Inc(i);
end;
setlength(s, j - 1);
end;
procedure ConvertJson(InName, OutName: string);
var
f : file of TCity;
sl: TStringList;
erg: string;
POI: TCity;
i, j : NativeInt;
begin
sl := TStringList.Create;
sl.loadfromfile(InName);
Assign(f,OutName);
Rewrite(f);
j := 0;
i := 0;
repeat
if Pos('{', sl[i]) > 0 then
break;
Inc(i);
until i >= sl.Count;
while i < sl.Count - 1 do
begin
erg := '';
for j := 0 to ZeilenProJSONDatum - 1 do
erg := erg + trim(sl[i + j]);
removeSpaceAfter(erg);//': '-> ':'
Split(erg,POI);
write(f,POI);
Inc(i, ZeilenProJSONDatum);
end;
SL.Free;
CloseFile(f);
end;
procedure ReadPOIs(OutName:String);
var
f:File of TCity;
i,j : integer;
Begin
Assign(f,OutName);
Reset(f);
i := FileSize(f);
writeln(i);
setlength(POIs,i);
dec(i);
For j:= 0 to i do
Read(f,POIs[j]);
CloseFile(f);
end;
procedure OutPOI(POIidx:NativeInt);
Begin
with POIs[POIidx] do
writeln(POIidx:8,ctID:8,ctCty:4,ctLon:12:6,ctLat:11:6,' ',ctName);
end;
procedure CheckCountry(s:String);
var
i,cnt : NativeInt;
Begin
IF length(s)<> 2 then
EXIT;
s:= Uppercase(s);
cnt := 0;
For i := 0 to High(POIs) do
If s = POIs[i].ctCty then
Begin
inc(cnt);
OutPOI(i);
end;
writeln('Es wurden ',cnt,' Übereinstimmungen gefunden');
end;
procedure CheckName(s:String);
var
i,cnt : NativeInt;
Begin
s:= lowercase(s);
cnt := 0;
For i := 0 to High(POIs) do
If POS(s,lowercase(POIs[i].ctName)) >0 then
Begin
OutPOI(i);
inc(cnt);
end;
writeln('Es wurden ',cnt,' Übereinstimmungen gefunden');
end;
begin
IF NOt(FileExists(cOutName)) then
Begin
IF NOT(FileExists(cInName)) then
Begin
writeln('Keine passende Datei ',cInName,' vorhanden');
HALT(-2);
end;
T0 := GetTickCount64;
ConvertJson(cInName, cOutName);
T1 := GetTickCount64;
Writeln(' Alles wegschreiben in ', T1 - T0, ' ms');
end;
IF NOT(FileExists(cOutName)) then
Begin
writeln('Keine passende Datei ',cOutName,' vorhanden');
HALT(-3);
end;
T0 := GetTickCount64;
ReadPOIs( cOutName);
T1 := GetTickCount64;
Writeln(' Alles einlesen in ', T1 - T0, ' ms');
T0 := GetTickCount64;
CheckCountry('ZA');
T1 := GetTickCount64;
Writeln(' Suche in ', T1 - T0, ' ms');
//Es wurden 555 Übereinstimmungen gefunden // "DE" über 27000 viele doppelt, oder ein paar m daneben
//Suche in 11 ms
T0 := GetTickCount64;
CheckName('bOurG');
T1 := GetTickCount64;
Writeln('Suche in ', T1 - T0, ' ms');
//Es wurden 156 Übereinstimmungen gefunden
//Suche in 17 ms
setlength(POIs,0);
end.
//erstmalig ohne cache eingelesen
Alles wegschreiben in 1142 ms
209579
Alles einlesen in 48 ms // ist dann im cache
//erstmalig ohne cache eingelesen
Alles einlesen in 280 ms // ~ 75 Mb/s
//viele Doppelte, waren wohl mal sortiert, die Daten
Nummer ID Cty Lon Lat Name
138553 2959628 DE 9.966100 54.313179 Achterwehr
138554 6553741 DE 7.066670 50.366699 Acht
138555 2959658 DE 7.066670 50.366669 Acht
138556 6556538 DE 12.933300 48.966702 Achslach
138557 2959660 DE 12.935110 48.971710 Achslach
138558 6553459 DE 7.650000 49.750000 Abtweiler
138559 2959747 DE 7.650000 49.750000 Abtweiler
138560 6555574 DE 10.001940 48.894958 Abtsgmünd
138561 2959766 DE 10.001720 48.895031 Abtsgmund
138562 2959771 DE 12.725260 51.889839 Abtsdorf
138563 6549952 DE 10.766700 51.250000 Abtsbessingen
138564 2959773 DE 10.766670 51.250000 Abtsbessingen
138565 6552160 DE 9.283330 53.966702 Aebtissinwisch
138566 2959779 DE 9.283330 53.966671 Aebtissinwisch
138567 6554718 DE 6.600000 49.783298 Aach
138568 2959944 DE 6.600000 49.783329 Aach
138569 6552984 DE 7.816670 52.566700 Eggermühlen
138570 3204947 DE 7.816670 52.566669 Eggermuhlen
138571 6554377 DE 6.997500 49.760899 Thalfang
138572 3204961 DE 7.000000 49.750000 Thalfang
...
138843 7932486 DE 9.993610 53.531109 Kleiner Grasbrook
138844 8051091 DE 11.193520 54.437801 Fehmarn
155517 2940418 DE 10.381910 52.090271 Calbecht
155518 2887164 DE 10.383330 52.066669 Kniestedt