Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Need help with placing a bullet or dot on an image at a specific x-y Coordinate

Status
Not open for further replies.

DougP

MIS
Dec 13, 1999
5,985
US
I have a WEB page that displays a blueprint of a store or warehouse. I am writing this in ASP.NET 4.5.
I would like to be able to position a dot or something on top of teh blueprint image whenever a user picks a location so they can esaily see where it is.
Psuedo code
RedDot.Filename = "/images/reddot.jpg"
Blueprint.Filename = "/images/Store48.jpg"
Aisle = "1A1"
RedDot.X = spLookupCoords(Aisle , "X") 'function to find the X coordinate, I can make this OK
RedDot.Y = spLookupCoords(Aisle , "Y")
So the red dot will show on top of the blueprint image at 405,512
Next time the user may pick B2C so teh dot needs to show at 603, 877. and so on.
My table has random samples:
Code:
Aisle  Xcoord   YCoord
1A1    405      512
1A2    405      519
B2C    603      877
etc


DougP
 
@DougP
let's assume that the coordinates are relative to the image of the blueprint. such that the top left would be 0,0
you'd need to know the coordinates of the bottom right edge too.
then determine the number of pixels (or ems etc) along the top and the height.
then convert the coordinates to pixels
then place the image in the same container as the blueprint, set its position to absolute and define top and left positions based on the pixels calculated above, taking into account the number of pixels in the dot image (so that the image is centred).

if you need more than the above, we'd need to know the relationship between coordinates and the height/width of the image.
 
jpadie, you have it exactly coorect. One issue I ran into before, when I wrote this in Microsoft Access 10 years ago, is each computer display has different pixels so it did not show up correctly on different monitors. Is there any way to allow for that?
Today there will be the issue of devices. desktop
But I don't care about that right now, just want to see a dot show up on my Win 8 Tablet.


DougP
 
Also back then I had a forn I opened and was able to click the image to get its X-Y coords. I wrote code to get that and also had a list of Aisle's already in a table. I selected an aisle from the grid, then clicked the Image, it grabed the X-Y cords and put them into the table. then I did the next one and so on. It took a long time.

DougP
 
DougP

so long as the script knows the coords of the top left and the bottom right you should be able to do the rest programmatically.

is this known data?
 
known data? yes think of a grocery store. the aisles are known ahead of time. lay a grid over the entire store/blueprint. Just like the game of Battleship.
So Campbells soup is on Aisle 6, Side B section 4, and cicking the image lets say thats 673, 983.
So if soemone wants to know where Campbell's soup is, they pick it then click Show on map and the red dot is there. Like google maps but for inside.


DougP
 
But I have no idea how to program java? Born and rasied in BASIC land, Need a start. was told to come here since HTML CSS would not do it.

DougP
 
sorry - we are miscommunicating!

i appreciate that there is a known list of aisles and coordinates. but I need to know whether before you start you know the coordinates of the bottom right hand corner. so that the coordinates describe a grid between 0,0 and x,y.

do you know the bottom right hand coordinates? if so I can write some code for you that will at least get you started.
 
And just so there is no confusions. Javascript is not Java. They are tangentially related, but are very different when it comes down to how they operate. Asking to do something in Java can result in drastically different things that Javascript. Specially if you try to run the Java code in a browser without a java runtime environment.


In any case, yes for a Javascript approach jpadie suggests which by the way is quote ingenious, you would also need to know the relationship between the coordinates, and the blueprint image's actual size in pixels, so you could establish that x,y coordinates are equal to "A" pixels from the left, and "B" pixels from the top.

If you can establish that say x456, y325 is the bottom right corner you can then extrapolate the position of other coordinates in pixels or ems.





----------------------------------
Phil AKA Vacunita
----------------------------------
Ignorance is not necessarily Bliss, case in point:
Unknown has caused an Unknown Error on Unknown and must be shutdown to prevent damage to Unknown.

Web & Tech
 
jpadie, this will be used for many stores, so at the upper side its 0,0 but the opposite corner might be 10,000 , 21,000. yes the final coords will be known and saved in the database too. the corners will be derived by clicking on the maps far corners prior to loading it. each maps farthest corner from 0,0 will be different. but that value will be known, yes.
so if you need numbers use 0,0 to 1000, 1200.
here is what I have so far
if you open the link and click "G" on the query keybaord shown. it will bring up items that start with "G". then lets say you pick the top item, Aisle: 9A2 | Green Giant H/F Lima beans. click the map button next to it, and it will show a map. I want the red dot to show at 9A2, which is aisle 9 the A= left side of it and 2 = 20% down the aisle.
you can see a red dot there now but its just at hard coded at 400, 500.



DougP
 
@DougP

i've knocked up this demo and code that should set you in the right direction. currently it uses a random wiki map and a couple of random bullets I found.

Code:
<!DOCTYPE HTML>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8">

<title>test page for DougP</title>
<script src="[URL unfurl="true"]http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>[/URL]
<script type="text/javascript">

var bullets = {
	redBullet: '[URL unfurl="true"]https://dl.dropboxusercontent.com/u/194358/tt/bullet_red.png',[/URL]
	blueBullet: '[URL unfurl="true"]https://dl.dropboxusercontent.com/u/194358/tt/bullet_blue.png'[/URL]
}
function placeImage(elem, bullet, coordx, coordy, maxcoordx, maxcoordy){	
	/*
	 * locate the container div
	 */
	var container = $(elem).closest('div');
	
	//set style of contained
	container.css({
		position:	'relative',
		display: 	'block' //should not be necessary
		});
	
	/*
	 * load bullet image and
	 * get its height and width
	 */ 
	var bulletImg = $('<img />').attr({
		src: bullets[bullet],
		width: 10 + 'px',
		height: 10 + 'px'
	}).hide();
	
	$('body').append(bulletImg);
	while(bulletImgH == 0) $.delay(500);
	var bulletImgH = bulletImg.height();
	var bulletImgW = bulletImg.width();
	
	console.log('line 34');
	/*
	 * map coords to pixels
	 */
	
	var xFactor = $(elem).width()/maxcoordx;
	var yFactor = $(elem).height()/maxcoordy;
	
	/*
	 * get centred pixel coords for the bullet
	 */
	var pixelX = coordx * xFactor;
	var pixelY = coordy * yFactor;
	
	/*
	 * adjust for size of bullet
	 */ 
	var pixelX = pixelX - (bulletImgW / 2);
	var pixelY = pixelY - (bulletImgH / 2);
	
	/*
	 * place the bullet on the map
	 */
	bulletImg.css({
		top:		pixelY + "px",
		left:		pixelX + "px",
		position:	'absolute',
		'z-index':	Math.floor(Math.random() * 100)
	}).insertAfter(elem).fadeIn(2500);
}

$(document).ready(function(){
	
	placeImage(	
				$('#myImg'),	//a jquery object of the blueprint, or a node reference
				'redBullet', 	//the corresponding key from the object above 
				2500, 2500, 	//x,y coords for the bullet placement
				5000, 5000		//x,y coords for the bottom left of the blueprint
			);
	
	placeImage(
				$('#myImg'),	//a jquery object of the blueprint, or a node reference
				'blueBullet', 	//the corresponding key from the object above 
				1300, 4000, 	//x,y coords for the bullet placement
				5000, 5000		//x,y coords for the bottom left of the blueprint
	);
});
</script>
</head>
<body>
	<div>
    	<img src="[URL unfurl="true"]http://upload.wikimedia.org/wikipedia/en/archive/7/7f/20100625011514!World_Map_flat_Mercator.png"[/URL] width="300px" id="myImg"/>
	</div>
</body>
</html>

I'm not a big UI person, but I suspect it would be a better experience to leave the map on the page and allow dots to be added to it dynamically, rather than causing people to navigate back and forward. to make this work, you would either have to do the coord lookup over ajax or download the database to the client as a json object. depending on the number of objects, and the likelihood of a customer being offline on a mobile client whilst in the store, the latter may well be better.
 
I have not coded for the 20% location as I assume your coordinate lookup function caters for that. if not post back with a sample of your coordinate database and the lookup function please
 
there is a requirement for jquery. by all means load the jquery minified code directly on the page (just copy and paste it to your page).

although there is a logical lacuna enabling a web page to work without the web ...
and I note that your current page loads jquery too, but an old and deprecated version thereof
 
Dougp
For the edification of future readers can you let us know whether this worked for you? Or if not what problems you are still having?
 
I was looking for something that did not require another function I don't know about. and want it inside my page which is aspx.
also I am leaning toward creating the store image as a drawing where it's created the rectangles and shapes instead of and image which can't be controlled and gets out of sync.


DougP
 
what is the 'other function you do not know about'?
are you talking about placeImage?
how were you intending to place the bullet on the image without some form of procedural code?
or is it that you do not understand the function? If so, just ask and it can be explained down to its basic components (although it is _very_ basic code already).

and want it inside my page which is aspx.
I don't understand that at all. what impact does the server-side choice of language have to do with the client side? asp just serves html, css and javascript. the code above is just javascript. you posted in a javascript forum. Can you help us understand what your issue is?

I am leaning toward creating the store image as a drawing where it's created the rectangles and shapes instead of and image which can't be controlled and gets out of sync

no idea what you mean by 'out of sync'. each image is static from the client's perspective. the client chooses which bullets to view on a per-request basis. there is no 'sync' to care about.
doing this server-side is _very_ sub-optimal. you will have to keep a cartesian product of all the locations and their resultant image files, and then determine dynamically, for each request, which one to server. I cannot think, myself, of a less good solution. You could, perhaps, process the image request dynamically each time, server-side. But this would be a (slightly less) terrible solution as you are (i) handling things server side that are idempotent and are better handled client-side (if only to save processor cycles); (ii) stopping the solution from using efficient ajax calls to add bullets to the blueprint.

the best solution here is

1. get the bullet coordinates from the database via ajax. NOT page refreshes
1a. it may be better to store all aisle coordinates client side. depends on the size of the database.
2. store the requested and plotted coordinates in localstorage for persistence.
3. plot the bullets on the blueprint client-side.

it would be the work of ten minutes to craft a solution to do this cradle-to-grave. and would significantly reduce server load.
 
it seems from your other thread that you have given up. i have no idea why.

however, as tek-tips is not just for your benefit but for the whole readership, I finished the solution that I proposed.

caveats:
1. I am using the single blueprint for each of the three stores, as you seem to do the same
2. you have not provided any method of obtaining the coordinates (or a database of the same) for each product. so my code generates a random set of coordinates for each product.
3. some of the products are duplicated (deliberately) to augment the list and make it more realistic
4. it is possible for the bullets (locations) to be outside the store map as the store map has a slight border. in real-life this will not happen as the coordinate will be properly set in a database.

the demo site is here: and the server side code is as follows
(note that this is written in php, but the code is extremely simple and can be ported into any language with no sweat.)
note also that the code currently uses getallproducts and does not use productlookup as the number of products in dougp's example site was only a few hundred. when this gets larger, it may be worth doing more controlled lookups.

Code:
<?php

class output{
	
	static public function error($message){
		echo json_encode(	array(
									'result'=>false, 
									'message'=>$message
									)
						);
		die;
	}
	
	static public function success($action, $data){
		echo json_encode( array(
								'result'=>'ok', 
								'action'=>$action, 
								'data'=>$data
								)
						);
		die;
		
	}
}
$pdo = new PDO('sqlite:test.sqlite');

$action = isset($_GET['action']) ? strtolower(trim($_GET['action'])) : '';

switch ($action):
	case 'getallproducts':
		if(!isset($_GET['storeid'])):
			output::error('insufficient data');
		endif;
		
		$sql = "Select id, aisle, product from products where storeid = ? ";
		$params = array( $_GET['storeid']);
		$s = $pdo->prepare($sql);
		if(!$s):
			$error = $pdo->errorInfo();
			output::error($error[2]);
		endif;
		$result = $s->execute($params);
		if(!$result):
			$error = $s->errorInfo();
			output::error($error[2]);
		endif;
		$results = $s->fetchAll( PDO::FETCH_ASSOC);
		output::success($action, $results);
		break;
	case 'productlookup':
		if(!isset($_GET['storeid']) || (!isset($_GET['search']))):
			output::error('insufficient data');
		endif;
		
		$sql = "Select id, aisle, product from products where storeid = ? and product like ? ";
		$params = array( $_GET['storeid'], "%" . $_GET['search'] . "%");
		$s = $pdo->prepare($sql);
		if(!$s):
			$error = $pdo->errorInfo();
			output::error($error[2]);
		endif;
		$result = $s->execute($params);
		if(!$result):
			$error = $s->errorInfo();
			output::error($error[2]);
		endif;
		$results = $s->fetchAll( PDO::FETCH_ASSOC);
		output::success($action, $results);
		break;
	case 'getcoords':
		if(!isset($_GET['storeid']) || (!isset($_GET['aisle']))):
			output::error('insufficient data');
		endif;
		
		/* stub out */
		$x = rand(1, 10000000)/1000;
		$y = rand(1, 10000000)/1000;
		output::success($action, array('top'=>$y, 'left'=>$x));
		
		/* end stub out */
		
		/* this would be how you returned the coordinates when they were properly populated */
		$sql = "Select TopLocation, LeftLocation, height,width where storeID = ? and aisle = ?";
		$params = array($_GET['storeid'], $_GET['aisle']);
		$s = $pdo->prepare($sql);
		if(!$s):
			$error = $pdo->errorInfo();
			output::error($error[2]);
		endif;
		$result = $s->execute($params);
		if(!$result):
			$error = $s->errorInfo();
			output::error($error[2]);
		endif;
		$row = $s->fetch( PDO::FETCH_ASSOC);
		output::success($action, $row);
		break;
	default:
		output::error("No valid action found");
endswitch;
?>
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top