Convert Latitude/Longitude to Web Mercator Pixels using PHP - php

I'm trying to convert WGS 84 coordinates into pixels using web mercator projection. I want to print the position on a given map. I came across a PHP function which works fine if the map is an image of the whole world. I've been trying hard to extend this function so it also works if the map is just a clip (e.g. North America). I already found a solution for calculating the width but I failed to adjust the height calculation. How do I have to change the function?
($top is the top left corner of the map image [Array], $bottom the bottom right corner / $this->width is map width, $this->height is map height)
function cor($lat = null, $lon = null, $top, $bottom) {
// Width
$width = ($lon-$bottom[1]) * $this->width/($top[1]-$bottom[1]);
// Height
$latrad = ($lat * M_PI) / 180;
$mercN = log(tan((M_PI / 4) + ($latrad / 2)));
$height = (($this->height / 2) - ($this->width * $mercN / (2 * M_PI)));
return Array($width, $height);
}
Thanks very much in advance! :)

Related

Write Text/Values On 360 degree Circle

I am working on a wheel chart design, I need help in positioning the text on the 360 wheel.
The wheel have 12 sections, each one of 30 degree. The text's offset from the circle outer line should be equal (or similar at least). like in the image below I have mocked up what I need in final result.
So far, What I have tried is splitting each section into separate variable e.g.
$section1_startX = 50;
$section1_endX = 70;
$section1_startY = 310;
$section1_endY = 480;
and then to place text
imagettftext($im, 15, 0, $section1_startX, $section1_startY, $black, $font, "05");
but this is to find/calculate pixels of each line I need to place.
I am sure there is better, dynamic and smart way to put the text at x,y positions based on its values in 360 circle.
can you please help me regarding?
Hi I think you want to find a Point on a given circle with a given degree. Here is a function for calculating point on a circle. I think you can convert this to any other language easily.
public static PointF PointOnCircle(float radius, float angleInDegrees, Point origin)
{
//radius -> Radius of Circle & Origin -> Circle Centre.
// Convert from degrees to radians via multiplication by PI/180
float x = (float)(radius * Math.Cos(angleInDegrees * Math.PI / 180F)) + origin.X;
float y = (float)(radius * Math.Sin(angleInDegrees * Math.PI / 180F)) + origin.Y;
return new PointF(x, y);
}

Calculating value depending on width or height of an image

I want to check if the height or the width of an image is bigger. Depending on that, a maximum value is defined. If it is a landscape image $limit = 1000; if it is a vertical format $limit = 600;
After this the image can be scaled correctly (maximum width 1000px or 600px depending on the format of the image). If the image is smaller than that, the image values are used. (Just downscaling).
Depending on Get dimensions to transform image to a maximum value I don't know how to realize these two different limit values:
$tmp = max($width, $height); # give me the bigger value
$limit = min($limit, $tmp); # if image dimension is lower, take that value
$factor = $tmp / $limit; # calculate factor to get the new dimensions
$new_width = $width / $factor;
$new_height = $height / $factor;
So this works great if there is only one limit-value (ie. 1000).
I just need the values, no real transforming of the image...
min(1, is only needed if you want only reduce big images and not resize smaller images:
$maxWidth = 1000;
$maxWidthIfVertical = 600;
$factor = $width > $height ? min(1, $maxWidth / $width) : min(1, $maxWidthIfVertical / $width);
$newWidth = $width * $factor;
$newHeight = $height * $factor;
Caution with this method, see the examples I added here: http://jsfiddle.net/Wornet/z3z6fcr3/4/ I think it's not realy what you want.
So I recommand this (limit 1000 in width, 800 in height):
http://jsfiddle.net/Wornet/z3z6fcr3/6/

How to restrict image width or height on upload

I would like manipulate/resize images in a similar way to Pinterest but I am not sure what is the best way to approach it. The goal is to allow a mix of both portrait and landscape images but put some restrictions on the maximum height and width.
The problem i can see is that if I resize to a width, a portrait image may become too thin, and the opposite it true for a landscape image.
Any ideas on how to achieve those sort of results with PHP?
You just need to understand which of the two edges of the image is longer, and compute the other dimension proportionally. If the maximum long-egde is 1024, then if one of the two edges is larger you will set that to 1024, and compute the other to fit the proportions. Then you will pass those two values to your image management functions.
Like here:
http://www.white-hat-web-design.co.uk/blog/resizing-images-with-php/
Or here:
http://www.9lessons.info/2009/03/upload-and-resize-image-with-php.html
try with this
$needheight = 1000;
$needwidth = 1000;
$arrtest = getimagesize($upload_image_physical_path);
$actualwidth = $arrtest[0];
$actualheight = $arrtest[1];
if($needwidth > $actualwidth || $needheight > $actualheight){
//uplaod code
}
cheers
Check for a max size and then resize based on a ratio. Here's a pseudo code example:
if($imageHeight > $maxHeight) {
$newHeight = $maxHeight;
$newWidth = $imageWidth * ($maxHeight / $imageHeight);
}
if($imageWidth > $maxWidth) {
$newWidth = $maxWidth;
$newHeight = $imageHeight * ($maxWidth / $imageWidth);
}
resize($image, $newWidth, $newHeight);
It first checks the height and if the height is greater, it scales it down. Then it checks the width. If the width is too big, it scales it down again. The end result, both height and width will be with in your bounds. It uses the ratio to do the scaling.
Note, this is pseudocodish. The actual resize function call will depend on your image manipulation library -- same goes for calls to obtain image size.

php resize image zoomcrop without border (logic)

i have a image manipulation class, i want to create images that always fill the entire new width and height so there are no borders/solid color background, i just cant understand how i can make it always fill the height and width (mantaining the aspect ratio of the uploaded image) if the image width AND height are smaller than the new image size..
just like the zoomcrop (zc=1) from phpthumb class (i looked the code from it but i couldnt mimic the behavior)
public function resizeCrop($newwidth, $newheight) {
...
$x = $this->getX();
$y = $this->getY();
...
else if ($x < $newwidth && $y < $newheight)
{
// logic ??
}
}
You need to make sure that the smaller (relative to the aspect ratio of the original image and that of container) side is zoomed to maximum. Have a look at this code:
public function resizeCrop($newwidth, $newheight) {
...
$x = $this->getX();
$y = $this->getY();
// old images width will fit
if(($x / $y) < ($newwidth/$newheight)){
$scale = $newwidth/$x;
$newX = 0;
$newY = - ($scale * $y - $newheight) / 2;
// else old image's height will fit
}else{
$scale = $newheight/$y;
$newX = - ($scale * $x - $newwidth) / 2;
$newY = 0;
}
// new image
$dest = imagecreatetruecolor($newwidth, $newheight);
// now use imagecopyresampled
imagecopyresampled($dest, $src, $newX, $newY, 0, 0, $scale * $x, $scale * $y, $x, $y);
return $dest;
}
Update: Corrected the function. It is now working perfectly, I have tested it on my dev machine.
To maintain aspect ratio, you need to choose: either make the image too big and then crop the original, or you make it fit just right and then fill in the parts that don't reach the edges with a solid color.
The former, you can compare the percentage change for width and height respectively, then use the larger percentage as a multiplier against both dimensions. For a 1 x 1 unit image that you want to fit into a 2w x 3h unit area and maintain aspect ratio: you can use a 3x multiplier, get a 3 x 3 unit image, and crop .5 units left/right.
The latter, you use the smaller percentage as a multiplier. For a 1 x 1 unit image that you want to fit into a 2w x 3h unit area and maintain aspect ratio: you can use a 2x multiplier, get a 2 x 2 unit image, and add .5 units of solid color top/bottom.

Resize image with PHP, detect longest side, and resize according?

I'm working on an image upload script with PHP, I found one someone was offering and tried modifying it, however, i'm running into a few problems.
I want to do the following:
Detect the longest side of the image (ie. portrait or landscape)
And then resize the image, with the longest side being 800px AND keep proportions.
Here is the code I have so far.. For landscape images it works fine, but with portrait ones it distorts them like crazy.
PS. I'm making a larger image as well as a thumbnail.
list($width,$height)=getimagesize($uploadedfile);
if($width > $height){
$newwidth=800;
$newheight=($height/$width)*$newwidth;
$newwidth1=150;
$newheight1=($height/$width)*$newwidth1;
} else {
$newheight=800;
$newwidth=($height/$width)*$newheight;
$newheight1=150;
$newwidth1=($height/$width)*$newheight;
}
$tmp=imagecreatetruecolor($newwidth,$newheight);
$tmp1=imagecreatetruecolor($newwidth1,$newheight1);
You're probably mistaking:
When $width > $height that means it's landscape. Setting maxwidth to 800 means (height/width)*800 = new height. On the other hand $height > $width means setting maxheight to 800 and thus having (width/height)*800 is new width.
Right now your using both the height/width ratio instead of the other way around. Example:
Image: 1600 (w) x 1200 (h)
Type: Landscape
New Width: 800
New Height: (1200 (h) / 1600(w) * 800 (nw) = 600
Image 1200 (w) x 1600 (h)
Type: Portrait
New Height: 800
New Width: (1200 (w) / 1600(h) * 800 (nh) = 600
Hope you get what I'm saying, you just switched them :) Also notice that you multiply with $newheight instead of $newheight1 for the portrait thumbnail
You can take a look in this function I use in my Image class:
public function ResizeProportional($MaxWidth, $MaxHeight)
{
$rate = $this->width / $this->height;
if ( $this->width / $MaxWidth > $this->height / $MaxHeight )
return $this->Resize($MaxWidth, $MaxWidth / $rate);
else
return $this->Resize($MaxHeight * $rate, $MaxHeight);
}
Basically it first calculates the image's proportions in $rate based on width/height. Then it checks if the width is going to get out of bounds when resized ( $this->width / $MaxWidth > $this->height / $MaxHeight ) and if it is - sets width to the desired maximum width and calculates the height accordingly.
$this->width / $MaxWidth is the percentage of the image's width based on the maximum one. So if $this->width / $MaxWidth is larger than $this->height / $MaxHeight the width should be set to maxwidth and the height should be calculated based on it. If the comparison is the other way around just set height to maxheight and calculate the new width.
You should switch height and width in the second part, note the ($width/$height) part:
} else {
$newheight=800;
$newwidth=($width/$height)*$newheight;
$newheight1=150;
$newwidth1=($width/$height)*$newheight;
}

Categories