summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--input_gadgets.c94
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);
}
}