#include #include #include #include #include #include #include /* This program employs the open source GD graphics library to read and create PNG images. GD is available from http://www.libgd.org/ Compile this program with: gcc -O -std=c99 -Wall -Werror -pedantic \ -I/path/to/gd/includes -o makemap makemap.c /path/to/gd/library/libgd.a -lpng -lm Compiled and tested on: Mac OS-X 10.5.4, with gcc v4.0.1 */ #include "gd.h" /* makemap (v1.0) Copyright (C) 2008-, Chris McDonald Chris McDonald, chris@csse.uwa.edu.au School of Computer Science & Software Engineering The University of Western Australia, Crawley, Western Australia, 6009 PH: +61 8 6488 2533, FAX: +61 8 6488 1089. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define AUTHOR_NAME "Chris McDonald" #define AUTHOR_EMAIL "chris@csse.uwa.edu.au" #define TILESQR 320 #define MODE_FILE 0644 #define MODE_DIR 0755 static char *argv0; static char *tilefmt; static int ncols = 0; static int nrows = 0; static void usage(int status) { fprintf(stderr, "Usage: %s mapname.png latitude0 longitude0 latitude1 longitude1\n", argv0); fprintf(stderr, "\nPlease report any bugs to %s, %s\n", AUTHOR_NAME, AUTHOR_EMAIL); exit(status); } static int make_tiles(const char *mapname, const char *filenm) { FILE *fp; fp = fopen(filenm, "r"); if(fp) { gdImagePtr im_in; int maxx, maxy; int ndigits=1; char fmt[MAXPATHLEN]; im_in = gdImageCreateFromPng(fp); fclose(fp); maxx = gdImageSX(im_in); maxy = gdImageSY(im_in); printf("%s.png is %dx%d pixels\n", mapname, maxx, maxy); sprintf(fmt, "map-%s", mapname); mkdir(fmt, MODE_DIR); chmod(fmt, MODE_DIR); printf("mkdir \"%s\"\n", fmt); sprintf(fmt, "map-%s/tiles", mapname); mkdir(fmt, MODE_DIR); chmod(fmt, MODE_DIR); ncols = maxx / TILESQR; nrows = maxy / TILESQR; if(ncols >= 100 || nrows >= 100) ndigits = 3; else if(ncols >= 10 || nrows >= 10) ndigits = 2; sprintf(fmt, "map-%s/tiles/tile-%%0%dd-%%0%dd.png", mapname, ndigits, ndigits); tilefmt = strdup( strchr(fmt, '/')+1 ); ncols = 0; nrows = 0; for(int x=0 ; (x*TILESQR) < maxx ; ++x) { int w, h; ++ncols; nrows = 0; w = maxx - (x*TILESQR); if(w > TILESQR) w = TILESQR; for(int y=0 ; (y*TILESQR) < maxy ; ++y) { char filenm[MAXPATHLEN]; gdImagePtr im_out; ++nrows; sprintf(filenm, fmt, x,y); unlink(filenm); h = maxy - (y*TILESQR); if(h > TILESQR) h = TILESQR; im_out = gdImageCreateTrueColor(w, h); gdImageCopy(im_out, im_in, 0, 0, x*TILESQR, y*TILESQR, w, h); fp = fopen(filenm, "w"); if(fp) { gdImagePng(im_out, fp); fclose(fp); chmod(filenm, MODE_FILE); } } } printf("%dx%d tiles created\n", ncols, nrows); gdImageDestroy(im_in); return 0; } usage(1); return 1; } static int make_mapinfo_plist(const char *mapname, double lat0, double lon0, double lat1, double lon1) { FILE *fp; char filenm[MAXPATHLEN]; sprintf(filenm, "map-%s/mapinfo.plist", mapname); fp = fopen(filenm, "w"); if(fp == NULL) return(1); fprintf(fp,"\n"); fprintf(fp,"\n"); fprintf(fp,"\n"); fprintf(fp,"\n"); fprintf(fp,"\tlat0\n"); fprintf(fp,"\t\t%lf\n", lat0); fprintf(fp,"\tlon0\n"); fprintf(fp,"\t\t%lf\n", lon0); fprintf(fp,"\tlat1\n"); fprintf(fp,"\t\t%lf\n", lat1); fprintf(fp,"\tlon1\n"); fprintf(fp,"\t\t%lf\n", lon1); fprintf(fp,"\n"); fprintf(fp,"\n"); fclose(fp); chmod(filenm, MODE_FILE); return 0; } static int make_html(const char *mapname) { FILE *fp; char filenm[MAXPATHLEN]; sprintf(filenm, "map-%s/tiles.html", mapname); fp = fopen(filenm, "w"); if(fp == NULL) return(1); fprintf(fp,"\n"); fprintf(fp,"\n"); fprintf(fp,"\n"); char *tdfmt = calloc(1, strlen(tilefmt) + 32); sprintf(tdfmt, "\t\n", tilefmt); for(int r=0 ; r\n"); for(int c=0 ; c\n"); } free(tdfmt); fprintf(fp,"
\n"); fprintf(fp,"\n"); fprintf(fp,"\n"); fclose(fp); chmod(filenm, MODE_FILE); return 0; } static double check_double(const char *str) { if(strspn(str, "-.0123456789") != strlen(str)) usage(1); return atof(str); } #define check_lat(x) if(x < -90.0 || x > 90.0) usage(1) #define check_lon(x) if(x < -180.0 || x > 180.0) usage(2) int main(int argc, char *argv[]) { double lat0, lon0; double lat1, lon1; char *mapname, *dot; int rtn; argv0 = (argv0 = strrchr(argv[0],'/')) ? argv0+1 : argv[0]; if(argc != 6) usage(1); mapname = (mapname = strrchr(argv[1],'/')) ? mapname+1 : argv[1]; mapname = strdup(mapname); dot = strrchr(mapname, '.'); if(dot == NULL || strcmp(dot, ".png") != 0) usage(1); *dot = '\0'; lat0 = check_double(argv[2]); check_lat(lat0); lon0 = check_double(argv[3]); check_lon(lon0); lat1 = check_double(argv[4]); check_lat(lat1); lon1 = check_double(argv[5]); check_lon(lon1); rtn = make_tiles(mapname, argv[1]); if(rtn == 0) rtn = make_mapinfo_plist(mapname, lat0, lon0, lat1, lon1); if(rtn == 0) rtn = make_html(mapname); return rtn; }