/*************************************************************************** * map_nodepois.c * * Copyright 2010 - Steffen Pohle * steffen@gulpe.de ****************************************************************************/ /* * 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. */ #include "map.h" #include "memoryleak.h" #include "system.h" /***************************************************** * * Place information Handling * */ /* * copy data for the place, the next value will be untouched */ void map_place_copy (struct map_place *dest, struct map_place *src) { int len = 5; // nullterminated chars inside char *next = dest->data; dest->country = next; if (src->country) { len += strlen (src->country); strcpy (dest->country, src->country); next = next + strlen (src->country); } next[0] = 0; next += 1; dest->state = next; if (src->state) { len += strlen (src->state); strcpy (dest->state, src->state); next = next + strlen (src->state); } next[0] = 0; next += 1; dest->district = next; if (src->district) { len += strlen (src->district); strcpy (dest->district, src->district); next = next + strlen (src->district); } next[0] = 0; next += 1; dest->name = next; if (src->name) { len += strlen (src->name); strcpy (dest->name, src->name); next = next + strlen (src->name); } next[0] = 0; next += 1; dest->postalcode = next; if (src->postalcode) { len += strlen (src->postalcode); strcpy (dest->postalcode, src->postalcode); next = next + strlen (src->postalcode); } next[0] = 0; next += 1; dest->type = src->type; dest->population = src->population; dest->id = src->id; dest->lon = src->lon; dest->lat = src->lat; }; int map_place_add (struct map_place *place, int loadflags) { struct map_hash *mh; int size; size = map_place_getsize (place) + POINTERALIGNMENT; mh = map_hash_get (place->lon, place->lat, loadflags); if (mh == NULL) { mh = map_hash_alloc (size + MAP_HASH_DEFAULTSIZE); mh->pos.ilon = map_geo2igeo (place->lon); mh->pos.ilat = map_geo2igeo (place->lat); map_hash_add (mh); } else if (size >= map_hash_getfree_size (mh)) { mh = map_hash_realloc (mh, mh->datasize + size + MAP_HASH_DEFAULTSIZE); } return map_place_add_to_hash (mh, place); }; int map_place_add_to_hash (struct map_hash *mh, struct map_place *place) { int size; struct map_place *p; /* check if the first element is already the one we want to update */ if (mh->places && mh->places->id == place->id) { mh->places = mh->places->next; mh->placescnt--; } /* find possible update and go to the end */ if (mh->places) { /* find last place */ p = mh->places; while (p && p->next) { if (p->next->id == place->id || p->id == place->id) { /* found old place.. just delete .. */ p->next = p->next->next; mh->placescnt--; } if (p->next) p = p->next; } p->next = (struct map_place*) map_hash_getfree_aligned (mh, POINTERALIGNMENT); p = p->next; } else { /* complete new ways */ mh->places = (struct map_place*) map_hash_getfree_aligned (mh, POINTERALIGNMENT); p = (struct map_place*) map_hash_getfree_aligned (mh, POINTERALIGNMENT); } /* copy the place data to the free entry * calc size and set free entry to it's new place */ size = map_place_getsize (place); map_place_copy (p, place); p->next = NULL; mh->free = ((void*)p) + size; mh->placescnt++; SETFLAG(mh->status, MS_changed); return 1; }; int map_place_getsize (struct map_place *place) { int size = 5 + sizeof (struct map_place); if (place->country) size += strlen (place->country); if (place->state) size += strlen (place->state); if (place->district) size += strlen (place->district); if (place->name) size += strlen (place->name); if (place->postalcode) size += strlen (place->postalcode); return size; }; /***************************************************** * * POI information Handling * */ void map_poi_copy (struct map_poi *dest, struct map_poi *src) { int len = 2; // nullterminated chars inside char *next = dest->data; dest->name = next; if (src->name) { len += strlen (src->name); strcpy (dest->name, src->name); next = next + strlen (src->name); } next[0] = 0; next += 1; dest->additional = next; if (src->additional) { len += strlen (src->additional); strcpy (dest->additional, src->additional); next = next + strlen (src->additional); } next[0] = 0; next += 1; dest->type = src->type; dest->id = src->id; dest->lon = src->lon; dest->lat = src->lat; }; int map_poi_add (struct map_poi *poi, int loadflags) { struct map_hash *mh; int size; size = map_poi_getsize (poi) + POINTERALIGNMENT; mh = map_hash_get (poi->lon, poi->lat, loadflags); if (mh == NULL) { mh = map_hash_alloc (size + MAP_HASH_DEFAULTSIZE); mh->pos.ilon = map_geo2igeo (poi->lon); mh->pos.ilat = map_geo2igeo (poi->lat); map_hash_add (mh); } else if (size >= map_hash_getfree_size (mh)) { mh = map_hash_realloc (mh, mh->datasize + size + MAP_HASH_DEFAULTSIZE); } return map_poi_add_to_hash (mh, poi); }; int map_poi_add_to_hash (struct map_hash *mh, struct map_poi *poi) { int size; struct map_poi *p; /* check if the first element is already the one we want to update */ if (mh->pois && mh->pois->id == poi->id) { mh->pois = mh->pois->next; mh->poiscnt--; } /* find possible update and go to the end */ if (mh->pois) { /* find last place */ p = mh->pois; while (p && p->next) { if (p->next->id == poi->id || p->id == poi->id) { /* found old place.. just delete .. */ p->next = p->next->next; mh->poiscnt--; } if (p->next) p = p->next; } p->next = (struct map_poi*) map_hash_getfree_aligned (mh, POINTERALIGNMENT); p = p->next; } else { /* complete new ways */ mh->pois = (struct map_poi*) map_hash_getfree_aligned (mh, POINTERALIGNMENT); p = (struct map_poi*) map_hash_getfree_aligned (mh, POINTERALIGNMENT); } /* copy the place data to the free entry * calc size and set free entry to it's new place */ size = map_poi_getsize (poi); map_poi_copy (p, poi); p->next = NULL; mh->free = ((void*)p) + size; mh->poiscnt++; SETFLAG(mh->status, MS_changed); return 1; }; int map_poi_getsize (struct map_poi *poi) { int size = 2 + sizeof (struct map_poi); if (poi->name) size += strlen (poi->name); if (poi->additional) size += strlen (poi->additional); return size; };