diff options
-rw-r--r-- | input_gadgets.c | 94 |
1 files changed, 92 insertions, 2 deletions
diff --git a/input_gadgets.c b/input_gadgets.c index 9076278..98f761f 100644 --- a/input_gadgets.c +++ b/input_gadgets.c @@ -36,6 +36,90 @@ WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) return realsize; } +int point_is_inside_polygon(double lat, double lon, char *text) +{ + char *input = malloc(strlen(text)+1); + if (input == NULL) { + fprintf(stderr, "malloc failed to allocate %d bytes\n", strlen(text)+1); + return -1; + } + strcpy(input, text); + double *lats = malloc(1); + if (lats == NULL) { + fprintf(stderr, "malloc failed to allocate 1 byte\n"); + free(input); + return -1; + } + double *lons = malloc(1); + if (lons == NULL) { + fprintf(stderr, "malloc failed to allocate 1 byte\n"); + free(lats); + free(input); + return -1; + } + int len = 0; + int alloc_len = 0; + char *q = NULL; + char *p = strtok_r(input, ",", &q); + while (p != NULL) { + if (alloc_len<=len) { + double *n; + alloc_len = len + 16; + n = realloc(lons, alloc_len*sizeof(lons[0])); + if (n == NULL) { + fprintf(stderr, "malloc failed to allocate %d byte\n", alloc_len*sizeof(lons[0])); + free(input); + free(lats); + free(lons); + return -1; + } + lons = n; + n = realloc(lats, alloc_len*sizeof(lats[0])); + if (n == NULL) { + fprintf(stderr, "malloc failed to allocate %d byte\n", alloc_len*sizeof(lats[0])); + free(input); + free(lats); + free(lons); + return -1; + } + lats = n; + } + lats[len] = atof(p); + p=strtok_r(NULL, " ", &q); + if (p == NULL) { + fprintf(stderr, "point_is_inside_polygon misses a space\n"); + free(input); + free(lats); + free(lons); + return -1; + } + lons[len] = atof(p); + p=strtok_r(NULL, ",", &q); + len++; + } + free(input); + if ((lons[0] != lons[len-1]) || (lats[0] != lats[len-1])) { + fprintf(stderr, "point_is_inside_polygon was given a non-closed polygon border\n"); + free(lats); + free(lons); + return -1; + } + int is_inside = 0; + for (int i=0; i<len-1; i++) { + if ((lat < lats[i]) && (lat <= lats[i+1])) + continue; + if ((lat > lats[i]) && (lat >= lats[i+1])) + continue; + if (lats[i] == lats[i+1]) + continue; + if ((lat - lats[i]) / (lats[i+1] - lats[i]) * (lons[i+1] - lons[i]) + lons[i] < lon) + is_inside = 1 - is_inside; + } + free(lats); + free(lons); + return is_inside; +} + char *gadgets_retrieve_current_temperature(char *output, int max_len) { CURL *curl_handle; @@ -653,8 +737,14 @@ char *gadgets_retrieve_weather_warnings(char *output, int max_len) xmlFreeDoc(doc); return NULL; } -/* if (point_is_inside_polygon(50.8830, 11.6223, text)) <<TODO>> - is_relevant = 1; */ + int ret = point_is_inside_polygon(50.8830, 11.6223, (char *)text); + if (ret == 1) + is_relevant = 1; + else if (ret != 0) { + fprintf(stderr, "point_is_inside_polygon failed to parse '%s'\n", (char *)text); + xmlFree(text); + return NULL; + } xmlFree(text); } } |