/*
* EasyWave - A realtime tsunami simulation program with GPU support.
* Copyright (C) 2014 Andrey Babeyko, Johannes Spazier
* GFZ German Research Centre for Geosciences (http://www.gfz-potsdam.de)
*
* Parts of this program (especially the GPU extension) were developed
* within the context of the following publicly funded project:
* - TRIDEC, EU 7th Framework Programme, Grant Agreement 258723
* (http://www.tridec-online.eu)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
#include
#include
#include
#include
#include "easywave.h"
//#define SSHMAX_TO_SINGLE_FILE 0
static int MaxPOIs;
int NPOIs;
static char **idPOI;
long *idxPOI;
static int *flagRunupPOI;
static int NtPOI;
static int *timePOI;
static float **sshPOI;
int ewLoadPOIs()
{
FILE *fp,*fpFit,*fpAcc,*fpRej;
int ierr,line;
int i,j,i0,j0,imin,imax,jmin,jmax,flag,it,n;
int rad,nmin,itype;
char record[256],buf[256],id[64];
double lon,lat,d2,d2min,lenLon,lenLat,depth;
double POIdistMax,POIdepthMin,POIdepthMax;
CNode& Node = *gNode;
// if POIs file is not specified
if( Par.filePOIs == NULL ) return 0;
Log.print("Loading POIs from %s", Par.filePOIs );
MaxPOIs = utlGetNumberOfRecords( Par.filePOIs ); if( !MaxPOIs ) return Err.post( "Empty POIs file" );
idPOI = new char*[MaxPOIs]; if( !idPOI ) return Err.post( Err.msgAllocateMem() );
idxPOI = new long[MaxPOIs]; if( !idxPOI ) return Err.post( Err.msgAllocateMem() );
flagRunupPOI = new int[MaxPOIs]; if( !flagRunupPOI ) return Err.post( Err.msgAllocateMem() );
sshPOI = new float*[MaxPOIs]; if( !sshPOI ) return Err.post( Err.msgAllocateMem() );
// read first record and get idea about the input type
fp = fopen( Par.filePOIs, "rt" );
line = 0; utlReadNextRecord( fp, record, &line );
itype = sscanf( record, "%s %s %s", buf, buf, buf );
fclose( fp );
if( itype == 2 ) { // poi-name and grid-index
fp = fopen( Par.filePOIs, "rt" );
line = NPOIs = 0;
while( utlReadNextRecord( fp, record, &line ) != EOF ) {
i = sscanf( record, "%s %d", id, &nmin );
if( i != 2 ) {
Log.print( "! Bad POI record: %s", record );
continue;
}
idPOI[NPOIs] = strdup(id);
idxPOI[NPOIs] = nmin;
flagRunupPOI[NPOIs] = 1;
NPOIs++;
}
fclose( fp );
Log.print( "%d POIs of %d loaded successfully; %d POIs rejected", NPOIs, MaxPOIs, (MaxPOIs-NPOIs) );
}
else if( itype == 3 ) { // poi-name and coordinates
if( Par.poiReport ) {
fpAcc = fopen( "poi_accepted.lst", "wt" );
fprintf( fpAcc, "ID lon lat lonIJ latIJ depthIJ dist[km]\n" );
fpRej = fopen( "poi_rejected.lst", "wt" );
}
lenLat = My_PI*Re/180;
fp = fopen( Par.filePOIs, "rt" );
line = NPOIs = 0;
while( utlReadNextRecord( fp, record, &line ) != EOF ) {
i = sscanf( record, "%s %lf %lf %d", id, &lon, &lat, &flag );
if( i == 3 )
flag = 1;
else if( i == 4 )
;
else {
Log.print( "! Bad POI record: %s", record );
if( Par.poiReport ) fprintf( fpRej, "%s\n", record );
continue;
}
// find the closest water grid node. Local distances could be treated as cartesian (2 min cell distortion at 60 degrees is only about 2 meters or 0.2%)
i0 = getI( lon );
j0 = getJ( lat );
if( i0<1 || i0>NLon || j0<1 || j0>NLat ) {
Log.print( "!POI out of grid: %s", record );
if( Par.poiReport ) fprintf( fpRej, "%s\n", record );
continue;
}
lenLon = lenLat * R6[j0];
for( nmin=-1,rad=0; rad NLon ) imax = NLon;
jmin = j0-rad; if( jmin < 1 ) jmin = 1;
jmax = j0+rad+1; if( jmax > NLat ) jmax = NLat;
for( i=imin; i<=imax; i++ )
for( j=jmin; j<=jmax; j++ ) {
if( i != imin && i != imax && j != jmin && j != jmax ) continue;
n = idx(j,i);
depth = Node(n, iD);
if( depth < Par.poiDepthMin || depth > Par.poiDepthMax ) continue;
d2 = pow( lenLon*(lon-getLon(i)), 2. ) + pow( lenLat*(lat-getLat(j)), 2. );
if( d2 < d2min ) { d2min = d2; nmin = n; }
}
if( nmin > 0 ) break;
}
if( sqrt(d2min) > Par.poiDistMax ) {
Log.print( "! Closest water node too far: %s", record );
if( Par.poiReport ) fprintf( fpRej, "%s\n", record );
continue;
}
idPOI[NPOIs] = strdup(id);
idxPOI[NPOIs] = nmin;
flagRunupPOI[NPOIs] = flag;
NPOIs++;
i = nmin/NLat + 1;
j = nmin - (i-1)*NLat + 1;
if( Par.poiReport ) fprintf( fpAcc, "%s %.4f %.4f %.4f %.4f %.1f %.3f\n", id, lon, lat, getLon(i), getLat(j), Node(nmin, iD), sqrt(d2min)/1000 );
}
fclose( fp );
Log.print( "%d POIs of %d loaded successfully; %d POIs rejected", NPOIs, MaxPOIs, (MaxPOIs-NPOIs) );
if( Par.poiReport ) {
fclose( fpAcc );
fclose( fpRej );
}
}
// if mareograms
if( Par.poiDt ) {
NtPOI = Par.timeMax/Par.poiDt + 1;
timePOI = new int[NtPOI];
for( it=0; it