views:

192

answers:

4

I have found the shape data for the borders of all the countries and a class to process it and I have written a script to convert the longitude and latitude to a pixel location on an image and to draw the countries using imagefilledpolygon and imageline. Everything is working great except:

1) I have a $scale variable that I can change. At $scale=1 the image is 360x180 pixel (1 pixel = 1 degree latitude/longitude). Ideally the final image I want would be about $scale = 2 (720x360) however the borderlines at 1 pixel thick look very thick. So I thought the best solution would be to generate the map at $scale=10 and then resize the generated image. The problem is imagecopyresized does not antialias when it resizes and it leaves me with a really jagged image, how can I resize and antialias?

2) The number of points to generate a polygon of a country is a LOT. The plan is to use the same code to produce an HTML imagemap to make the countries into links. However I fear at the moment there are too many points for an imagemap (the file size might be too big). My initial approach was to skip x amount of points, which lead to some success, If I process 1 in 10 points I get an acceptable result mostly. Ideally I would have even less... when I tried 1 in 40 I found some country borders overlapped and there were some gaps between countries (but some of the busier coastlines looked better). What is a sensible way to reduce the number of points whilst maintaining a reasonable level of accuracy?

If anyone is interested I'll post the code (once it's finished.)

A: 

So I don't have any code for this, its more of just an idea for your second problem. Can your classes that generate the map take an x/y coordinate and determine which country you are in?

If you can, than you could avoid using an image map and just use javascript to determine what the x/y coordinate of the click was. Resolve this into a location and act on it as you would normally. Downside of this of course is that if javascript is turned off it won't work.

Sounds neat though.

raytiley
That could work with ajax: store all the points on the server and then when the user clicks query the xy mouse click... yes I can see that working. Problem is I wanted mouse over data (country name)... I think if there was an ajax request on every mouse movement might be a bit heavy :)
Mark
yeah... definitely not for every movement :)
raytiley
A: 

Solved the first one:

imagecopyresampled is the function I needed not imagecopyresized

Mark
A: 

For the second part of your problem, what you need to do is not use every 10th point, but only use the ones that add something to the map. You could try only using a point if it is over some threshold distance from the last point rendered. That would mean in denser areas you use less points, but when they're spaced out you use as many as you need.

justinlatimer
yeh, I was considering that... I have a feeling I may still have the same problem where it takes out important points leaving a gap between two countries or causing an overlap. I guess there is no harm in trying.
Mark
Well, you can always tweak the results by changing the threshold distance if you find you're getting too many or not enough points.
justinlatimer
+2  A: 

For the simplification/approximation of the curves take a look at http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker%5Falgorithm

VolkerK