diff --git a/mapserver/Dockerfile b/mapserver/Dockerfile index 4982922f612c61545f4c07e9763f387df8934e28..75d218c700991b6f5bc99f3af66bc90981619310 100644 --- a/mapserver/Dockerfile +++ b/mapserver/Dockerfile @@ -54,6 +54,7 @@ COPY cgi-bin/* /usr/lib/cgi-bin/ # Point apache to the mapserver binary RUN ln -s /usr/local/bin/mapserv /usr/lib/cgi-bin/mapserv && \ + ln -s /usr/local/bin/mapserv /usr/lib/cgi-bin/mapserv.fcgi && \ chown ${APACHE_RUN_USER}:${APACHE_RUN_GROUP} /usr/lib/cgi-bin/* && \ chown -h ${APACHE_RUN_USER}:${APACHE_RUN_GROUP} /usr/lib/cgi-bin/* @@ -66,6 +67,9 @@ COPY html/ /var/www/html/ COPY sql/ /work/sql/ RUN sqlite3 -init /work/sql/goesr_crs.sql /usr/local/share/proj/proj.db +# Check the config before we finish +RUN apache2ctl configtest + # https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop STOPSIGNAL WINCH diff --git a/mapserver/mapfiles/g16_abi_radf_l1b.map b/mapserver/mapfiles/g16_abi_radf_l1b.map index d989dc4c112317afecca7c6e324e3ec384f5784b..384b7034056b514e4bd5868d9f991b70147f13d5 100644 --- a/mapserver/mapfiles/g16_abi_radf_l1b.map +++ b/mapserver/mapfiles/g16_abi_radf_l1b.map @@ -1,7 +1,8 @@ MAP IMAGETYPE PNG SIZE 256 256 - EXTENT -180 -90 180 90 + EXTENT -5434894.885 -5434894.885 5434894.885 5434894.885 + #EXTENT -180 -90 180 90 PROJECTION "init=epsg:930916" diff --git a/mapserver/site-conf b/mapserver/site-conf index 0c812d2e18e49146c1dfb537f702802b4f65e8f5..b83c316d3b5534c4601d956644a1e4fbfd7fbea4 100644 --- a/mapserver/site-conf +++ b/mapserver/site-conf @@ -28,16 +28,25 @@ #Include conf-available/serve-cgi-bin.conf # Custom CSPP Geo - # LoadModule rewrite_module modules/mod_rewrite.so RewriteEngine on # /wms/goes16/abi/fldk/ RewriteRule "^/wms/([^/]+)/([^/]+)/([^/]+)/l1b?(.*)" "/cgi-bin/mapserv?map=/work/mapfiles/$1_$2_$3_l1b.map&$4" [PT,QSA] + # FCGI version of the above + RewriteRule "^/fwms/([^/]+)/([^/]+)/([^/]+)/l1b?(.*)" "/cgi-bin/mapserv.fcgi?map=/work/mapfiles/$1_$2_$3_l1b.map&$4" [PT,QSA] # /wms_times/g16/abi/radf/true_color RewriteRule "^/wms_times/([^/]+)/([^/]+)/([^/]+)/([^/]+)" "/cgi-bin/layer_times.py?layer=/data/tiles/$1/$2/$3/$4/$4.shp" [PT,QSA] # FIXME: We need to include the sector # /data/goes/grb/goes16/2020/2020_01_21_021/abi/L1b/RadF/GOES-16_ABI_RadF_C01_20200121_000016_GOES-East.tif # "/data/tiles/g16/abi/radf/true_color/true_color" LogLevel alert rewrite:trace6 + + # handler should be added by the enabled module + #AddHandler fcgid-script fcgi + <IfModule mod_fcgid.c> + FcgidMaxProcessesPerClass 30 + FcgidInitialEnv PROJ_LIB /usr/local/share/proj + FcgidInitialEnv LD_LIBRARY_PATH "/usr/local/lib:/usr/local/pgsql/lib:/usr3/pkg3/oracle9/lib" + </IfModule> </VirtualHost> # vim: syntax=apache ts=4 sw=4 sts=4 sr noet \ No newline at end of file diff --git a/tile_gen/Dockerfile b/tile_gen/Dockerfile index 125540c43684370b59e725755a438fbf2982bb40..e51a66e8f631d3acc843953c71520fdc614d53c3 100644 --- a/tile_gen/Dockerfile +++ b/tile_gen/Dockerfile @@ -2,7 +2,6 @@ FROM tiledb/tiledb-geospatial:latest WORKDIR /work -# TODO may need the unzip command to be installed if not already RUN apt-get update && apt-get install -y unzip && \ wget http://ssec.wisc.edu/~rayg/pub/amqpfind.zip && \ unzip amqpfind.zip && \ diff --git a/tile_gen/generate_tiles.py b/tile_gen/generate_tiles.py index 2312f6b1c800bf047d9eab36a0b3a8306e004793..0a5c7e8c5158f07c994cbacc6c636f6e3c486f17 100644 --- a/tile_gen/generate_tiles.py +++ b/tile_gen/generate_tiles.py @@ -6,6 +6,7 @@ import warnings import logging import subprocess import shutil +import json from glob import glob import tile_index @@ -71,6 +72,11 @@ def main(): help="Shapefile filename pattern to use and placed " "in the output directory. " "(default: '{product}.shp')") + parser.add_argument('--json-times', action='store_true', + help="Print a JSON dict to stdout containing removed " + "and added times (ex. '{\'times_removed\': [], " + "\'times_added\': []}'). Times are in the form: " + "YYYY-MM-DDTHH:MM:SS.") parser.add_argument('out_dir', help="Output path to save tile information to (ex. '/data/tiles/{product}')") parser.add_argument('input_files', nargs="+", @@ -78,6 +84,8 @@ def main(): args = parser.parse_args() groups = group_files(args.products, args.input_files) + all_added = set() + all_removed = set() for prod, prod_files in groups.items(): out_dir = args.out_dir.format(product=prod) os.makedirs(out_dir, exist_ok=True) @@ -97,8 +105,14 @@ def main(): # create shape file LOG.info("Rebuilding shapefile index with:\n\t{}".format(", ".join(all_prod_files))) - tile_index.index(all_prod_files, shp_pathname) - + removed_times, added_times = tile_index.index(all_prod_files, shp_pathname) + all_removed.update(removed_times) + all_added.update(added_times) + + if args.json_times: + all_removed = [x.isoformat() for x in sorted(all_removed)] + all_added = [x.isoformat() for x in sorted(all_added)] + print(json.dumps({'removed_times': all_removed, 'added_times': all_added})) if __name__ == "__main__": diff --git a/tile_gen/run.sh b/tile_gen/run.sh index 449169bbe594746a7cd09bca1f245ccb7579816b..7501bea2c61206b36cd6fc710e237427b5054253 100755 --- a/tile_gen/run.sh +++ b/tile_gen/run.sh @@ -16,7 +16,7 @@ test -d "/data" export AMQPFIND_ARGS=${AMQPFIND_ARGS:-"-H cspp-geo-rabbit -X satellite -u guest -p guest"} -export AMQPSEND_ARGS=${AMQPSEND_ARGS:-"-H cspp-geo-rabbit -X satellite -u guest -p guest"} +export AMQPSEND_ARGS=${AMQPSEND_ARGS:-"-D 15 -H cspp-geo-rabbit -X satellite -u guest -p guest"} export AMQPFIND_TOPIC=${AMQPFIND_TOPIC:-'data.goes.*.abi.*.l1b.geotiff.complete'} export G2G_PRODUCTS=${G2G_PRODUCTS:-"C01 C02 C03 C04 C05 C06 C07 C08 C09 C10 C11 C12 C13 C14 C15 C16 true_color"} export TILE_ARGS=${TILE_ARGS:-""} @@ -62,16 +62,20 @@ run_tile_gen() { out_dir="${out_dir}/{product}" fi echo "Generating tiles in directory: ${out_dir}" - python3 generate_tiles.py ${TILE_ARGS} -p ${G2G_PRODUCTS} -- ${out_dir} ${path} - # OUT/<product>/<product>.shp - glob_pattern="${out_dir}/*/*.shp" - # Remove the /data prefix - glob_pattern="${glob_pattern/${dst_dir}\//}" + for product in ${G2G_PRODUCTS}; do + json_times_changed=$(python3 generate_tiles.py ${TILE_ARGS} --json-times -p ${product} -- ${out_dir} ${path}) + # OUT/<product>/<product>.shp + glob_pattern="${out_dir}/${product}/*.shp" + # Remove the /data prefix + glob_pattern="${glob_pattern/${dst_dir}\//}" - amqpsend_topic="data.${satellite_family}.${satellite_id}.${instrument}.${data_type}.l1b.tiledb.complete" -# json_info="{path: ${glob_pattern}, satellite_family: ${satellite_family}, satellite_ID: ${satellite_id}, instrument: ${instrument}, data_type: ${data_type}}" - json_info="{\"path\": \"${glob_pattern}\", \"satellite_family\": \"${satellite_family}\", \"satellite_ID\": \"${satellite_id}\", \"instrument\": \"${instrument}\", \"data_type\": \"${data_type}\"}" - echo -e "[[\"$amqpsend_topic\", $json_info]]" | python3 /work/amqpfind/amqpsend.py ${AMQPSEND_ARGS} + amqpsend_topic="data.${satellite_family}.${satellite_id}.${instrument}.${data_type}.l1b.tiles.${product}.complete" + json_info="{\"path\": \"${glob_pattern}\", \"satellite_family\": \"${satellite_family}\", \"satellite_ID\": \"${satellite_id}\", \"instrument\": \"${instrument}\", \"data_type\": \"${data_type}\", \"product\": \"${product}\"}" + # append the JSON returned by the python (remove the curly braces at the ends) + json_info="${json_info:0:-1}, ${json_times_changed:1}" + echo -e "[[\"$amqpsend_topic\", $json_info]]" + echo -e "[[\"$amqpsend_topic\", $json_info]]" | python3 /work/amqpfind/amqpsend.py ${AMQPSEND_ARGS} + done echo "Done generating tiles for ${path}" } diff --git a/tile_gen/tile_index.py b/tile_gen/tile_index.py index 6ff1769ef093322586201601cdc4432279c55e6f..2514c4b29d1fe7b4d676fbb787aff190a4a28d38 100644 --- a/tile_gen/tile_index.py +++ b/tile_gen/tile_index.py @@ -41,6 +41,18 @@ possible_time_regex = ( ) +def get_current_times(shp_filename): + """Get currently available times in the shapefile.""" + if not os.path.isfile(shp_filename): + # no shapefile, no times + return + + with fiona.open(shp_filename, 'r') as shp_file: + for time_step in shp_file: + t = time_step['properties']['time'] + yield datetime.datetime.strptime(t, '%Y-%m-%dT%H:%M:%S') + + def get_file_time(fn): for regex, time_fmt in possible_time_regex: matches = regex.findall(fn) @@ -57,16 +69,23 @@ def index(input_files, output_shapefile): once. Repeated calls to this function will overwrite existing shapefile information. + Returns: + (times_removed, times_added): Two lists of times removed by this index + being updated and times added by this index being updated. + """ import tempfile out_dir, shp_fn = os.path.split(output_shapefile) tmp_dir = tempfile.mkdtemp("_tile_index") tmp_shapefile = os.path.join(tmp_dir, shp_fn) + current_times = set(get_current_times(output_shapefile)) + new_times = set() with fiona.open(tmp_shapefile, 'w', driver='ESRI Shapefile', schema=temporal_schema) as output: for f in input_files: try: dt = get_file_time(f) + new_times.add(dt) except ValueError: logger.error(f"Can't time for file {f}") continue @@ -90,6 +109,10 @@ def index(input_files, output_shapefile): # we don't need the temporary directory anymore shutil.rmtree(tmp_dir, ignore_errors=True) + times_removed = current_times - new_times + times_added = new_times = current_times + return sorted(times_removed), sorted(times_added) + # def index(src_dir, output): # files = glob.glob(os.path.join(src_dir, '*.tif'))