且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用Google地图API计算从已知点到路线中最近点的距离

更新时间:2023-08-30 12:54:28

一个解决方案:


  1. 从每条路线中提取多段线

  2. 处理每条多段线,找到最近的点(使用直线,与乌鸦飞行距离)





  //使用这个新的渲染器和结果
renderArray [I] .setDirections(结果);
//并开始下一个请求
var polyline = getPolyline(result);
var marker = new google.maps.Marker({
position:getClosestPoint(referencePt,polyline),
map:map,
icon:iconArray [i]
});
nextRequest();

概念证明小提琴



代码段:

  var referencePt =TBD; //初始化一些变量var directionsService = new google.maps.DirectionsService(); var num,map,data; var requestArray = [],renderArray = []; var markerBounds = new google.maps.LatLngBounds(); //包含一些人/路线和目的地/ stopsvar的JSON数组jsonArray = {Blue Run:[300 University Ave,Plant 1 Belleville,ON K8N 5T7,3900 West Hamlin 运行:[5811-99th Avenue Kenosha,WI 53144,46600 Port St Plymouth,MI 48170],缓慢运行:[2152 North Talbot Road Windsor, ON N9A 6J3,46600 Port St Plymouth,MI 48170,2968 Waterview Rochester Hills,MI 48309,4350 Camp Ground Rd Rd Louisville,KY 40216]} // 16导航的标准颜色polylinesvar colourArray = ['navy','red','green','gray','fuchsia','black','white','lime ','栗色','紫色','aqua','银色','橄榄色','蓝色','黄色','深青色']; var iconArray = [http://maps.google.com/ mapfiles / ms / icons / blue.png,http://maps.google.com/mapfiles/ms/icons/red.png,http://maps.google.com/mapfiles/ms/icons/ green.png]; //让我们创建一个请求数组,它将成为map上的单个多段线。function generateRequests(){requestArray = []; for(var in jsonArray){//现在处理其中一个人/路线//某处存储路点var waypts = []; //'start'和'finish'将是路线的起点和终点var start,finish // lastpoint用于确保重复的航点被剥离var lastpoint data = jsonArray [route] limit = data.length for(var waypoint = 0; waypoint< limit; waypoint ++){if(data [waypoint] === lastpoint){//最后一个航点的重复 - 不要继续; } //为下一个循环准备最后一个点lastpoint = data [waypoint] //将这个点添加到数组中,用于发出请求waypts.push({location:data [waypoint],stopover:true}); } //获取'start'位置的第一个航点start =(waypts.shift())。 //抓取最后一个航点用作完成位置finish = waypts.pop();如果(完成=== undefined){//除非由于某种原因没有完成位置?完成=开始; } else {finish = finish.location; } //创建Google Maps请求对象var request = {origin:start,destination:finish,waypoints:waypts,travelMode:google.maps.TravelMode.DRIVING}; //并将其保存在我们的requestArray requestArray.push({route:route,request:request}); } processRequests();} function processRequests(){//计数器跟踪请求提交并一次处理一个; var i = 0; //用于提交请求'i'函数submitRequest(){directionsService.route(requestArray [i] .request,directionResults); } //作为上述请求的回调,用于当前'i'函数directionResults(result,status){if(status == google.maps.DirectionsStatus.OK){//创建一个独特的DirectionsRenderer'i'renderArray [i] = new google.maps.DirectionsRenderer(); renderArray [I] .setMap(地图); // colorArray的一些独特选项,所以我们可以看到路线renderArray [i] .setOptions({preserveViewport:true,suppressInfoWindows:true,polylineOptions:{strokeWeight:4,strokeOpacity:0.8,strokeColor:colourArray [i]},markerOptions :{icon:{path:google.maps.SymbolPath.BACKWARD_CLOSED_ARROW,scale:4,strokeColor:colourArray [i]},clickable:true,title:'Boo yeah!'}}); //使用这个新的渲染器和结果renderArray [i] .setDirections(result); //并开始下一个请求var polyline = getPolyline(result); var marker = new google.maps.Marker({position:getClosestPoint(referencePt,polyline),map:map,icon:iconArray [i]}); markerBounds.extend(marker.getPosition()); nextRequest(); }} function nextRequest(){//增加计数器i ++; //确保我们仍在等待请求if(i> requestArray.length){map.fitBounds(markerBounds); //没有更多的事情要做; } //提交另一个请求submitRequest(); } //这个请求只是启动整个过程submitRequest();} getPolyline(result){var polyline = new google.maps.Polyline({path:[]}); var path = result.routes [0] .overview_path; var legs = result.routes [0] .legs; for(i = 0; i< legs.length; i ++){var steps = legs [i] .steps; for(j = 0; j $ p $  

 

margin:0px; padding:0px}#map-canvas {float:left;宽度:70%; height:100%;}#panel {position:absolute; top:5px;剩下:50%; margin-left:-180px; z-index:5; background-color:#fff;填充:5px; border:1px solid#999;}#control_panel {float:right;宽度:30%; text-align:left; padding-top:20px;}

$ c>< script src = https://maps.googleapis.com/maps/api/js?libraries=geometry\"&gt ;</script><div id =map-canvas>< / div>< div id = CONTROL_PANEL &GT; < div class =containerstyle =width:auto;> &LT; H1&GT;旅程:其中/ H1&GT; < div class =panel panel-default> < div class =panel-heading> < h3 class =panel-title> Blue Run< / h3> &LT; / DIV&GT; < div class =panel-body> &LT;醇&GT; < li>< strong> Autosystems(大学)< / strong> < br /> 300 University Ave,Plant 1 Belleville,ON K8N 5T7< / li> < li>< strong> Fanuc America< / strong> < br /> 3900 West Hamlin Road Rochester Hills,MI 48309< / li> &LT; /醇&GT; &LT; / DIV&GT; &LT; / DIV&GT; < div class =panel panel-default> < div class =panel-heading> < h3 class =panel-title> Big Run< / h3> &LT; / DIV&GT; < div class =panel-body> &LT;醇&GT; < li>< strong> Asyst Technologies< / strong> < br /> 5811-99th Avenue Kenosha,WI 53144< / li> < li>< strong> Autosystems America Inc< / strong> < br /> 46600 Port St Plymouth,MI 48170< / li> &LT; /醇&GT; &LT; / DIV&GT; &LT; / DIV&GT; < div class =panel panel-default> < div class =panel-heading> < h3 class =panel-title>慢跑< / h3> &LT; / DIV&GT; < div class =panel-body> &LT;醇&GT; < li>< strong> A B自动化< / strong> < br />> 2155 North Talbot Road Windsor,ON N9A 6J3< / li> < li>< strong> Autosystems America Inc< / strong> < br /> 46600 Port St Plymouth,MI 48170< / li> < li>< strong>工业自动化< / strong> < br /> 2968 Waterview Rochester Hills,MI 48309< / li> < li>< strong> Arkema Inc.< / strong> < br /> 4350 Campground Rd Louisville,KY 40216< / li> &LT; /醇&GT; &LT; / DIV&GT; &LT; / DIV&GT; < / div>< / div>< input type =hiddenname =latid =latvalue =/>< input type =hiddenname =lng lngvalue =/>


I am working on a project that displays a map with multiple routes. I need to be able to search by an address and return the distance to the closest point within each of the routes. It's easy to measure distance from known points but I need to know the distance from a known point to the closest point along a route.

Here is the code that maps out 3 routes and a single point with a 50km radius circle around it. I need to measure from that point to the closest point on each route.

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta charset="utf-8" />
<title>Waypoints in directions</title>
<!-- Latest compiled and minified CSS -->

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" />

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css" />

<!-- Latest compiled and minified JavaScript -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>

<style>

html, body, #map-canvas {
    height: 100%;
    margin: 0px;
    padding: 0px
}

#map-canvas {
    float:left;
    width:70%;
    height:100%;
}

#panel {
    position: absolute;
    top: 5px;
    left: 50%;
    margin-left: -180px;
    z-index: 5;
    background-color: #fff;
    padding: 5px;
    border: 1px solid #999;
}

#control_panel {
    float:right;
    width:30%;
    text-align:left;
    padding-top:20px;
}

</style>

</head>
<body>

<div id="map-canvas"></div>
<div id="control_panel">

    <div class="container" style="width:auto;">
        <h1>Trips:</h1>


        <div class="panel panel-default">
            <div class="panel-heading">
                <h3 class="panel-title">Blue Run</h3>
            </div>
            <div class="panel-body">
                <ol>
<li><strong>Autosystems (University)</strong><br />300 University Ave, Plant 1 Belleville, ON K8N 5T7</li><li><strong>Fanuc America</strong><br />3900 West Hamlin Road Rochester Hills, MI 48309</li>                </ol>
            </div>
        </div>

        <div class="panel panel-default">
            <div class="panel-heading">
                <h3 class="panel-title">Big Run</h3>
            </div>
            <div class="panel-body">
                <ol>
<li><strong>Asyst Technologies</strong><br />5811 - 99th Avenue Kenosha, WI 53144</li><li><strong>Autosystems America Inc</strong><br />46600 Port St Plymouth, MI 48170</li>                </ol>
            </div>
        </div>

        <div class="panel panel-default">
            <div class="panel-heading">
                <h3 class="panel-title">Slow Run</h3>
            </div>
            <div class="panel-body">
                <ol>
<li><strong>A B Automation</strong><br />2155 North Talbot Road Windsor, ON N9A 6J3</li><li><strong>Autosystems America Inc</strong><br />46600 Port St Plymouth, MI 48170</li><li><strong>Industrial Automation</strong><br />2968 Waterview Rochester Hills, MI 48309</li><li><strong>Arkema Inc.</strong><br />4350 Campground Rd Louisville, KY 40216</li>                </ol>
            </div>
        </div>
    </div>

</div>

<input type="hidden" name="lat" id="lat" value="" />
<input type="hidden" name="lng" id="lng" value="" />

<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=<api-key>"></script>
<script type="text/javascript">

// Initialize some variables
var directionsService = new google.maps.DirectionsService();
var num, map, data;
var requestArray = [], renderArray = [];

// A JSON Array containing some people/routes and the destinations/stops
var jsonArray = {
    "Blue Run": ["300 University Ave, Plant 1 Belleville, ON K8N 5T7","3900 West Hamlin Road Rochester Hills, MI 48309"],
    "Big Run": ["5811 - 99th Avenue Kenosha, WI 53144","46600 Port St Plymouth, MI 48170"],
    "Slow Run": ["2155 North Talbot Road Windsor, ON N9A 6J3","46600 Port St Plymouth, MI 48170","2968 Waterview Rochester Hills, MI 48309","4350 Campground Rd Louisville, KY 40216"]
}

// 16 Standard Colours for navigation polylines
var colourArray = ['navy', 'red', 'green', 'grey', 'fuchsia', 'black', 'white', 'lime', 'maroon', 'purple', 'aqua', 'silver', 'olive', 'blue', 'yellow', 'teal'];

// Let's make an array of requests which will become individual polylines on the map.
function generateRequests(){

    requestArray = [];

    for (var route in jsonArray){
        // This now deals with one of the people / routes

        // Somewhere to store the wayoints
        var waypts = [];

        // 'start' and 'finish' will be the routes origin and destination
        var start, finish

        // lastpoint is used to ensure that duplicate waypoints are stripped
        var lastpoint

        data = jsonArray[route]

        limit = data.length
        for (var waypoint = 0; waypoint < limit; waypoint++) {
            if (data[waypoint] === lastpoint){
                // Duplicate of of the last waypoint - don't bother
                continue;
            }

            // Prepare the lastpoint for the next loop
            lastpoint = data[waypoint]

            // Add this to waypoint to the array for making the request
            waypts.push({
                location: data[waypoint],
                stopover: true
            });
        }

        // Grab the first waypoint for the 'start' location
        start = (waypts.shift()).location;
        // Grab the last waypoint for use as a 'finish' location
        finish = waypts.pop();
        if(finish === undefined){
            // Unless there was no finish location for some reason?
            finish = start;
        } else {
            finish = finish.location;
        }

        // Let's create the Google Maps request object
        var request = {
            origin: start,
            destination: finish,
            waypoints: waypts,
            travelMode: google.maps.TravelMode.DRIVING
        };

        // and save it in our requestArray
        requestArray.push({"route": route, "request": request});
    }

    processRequests();
}

function processRequests(){

    // Counter to track request submission and process one at a time;
    var i = 0;

    // Used to submit the request 'i'
    function submitRequest(){
        directionsService.route(requestArray[i].request, directionResults);
    }

    // Used as callback for the above request for current 'i'
    function directionResults(result, status) {
        if (status == google.maps.DirectionsStatus.OK) {

            // Create a unique DirectionsRenderer 'i'
            renderArray[i] = new google.maps.DirectionsRenderer();
            renderArray[i].setMap(map);

            // Some unique options from the colorArray so we can see the routes
            renderArray[i].setOptions({
                preserveViewport: true,
                suppressInfoWindows: true,
                polylineOptions: {
                    strokeWeight: 4,
                    strokeOpacity: 0.8,
                    strokeColor: colourArray[i]
                },
                markerOptions:{
                    icon:{
                        path: google.maps.SymbolPath.BACKWARD_CLOSED_ARROW,
                        scale: 4,
                        strokeColor: colourArray[i]
                    },
                    clickable: true,
                    title: 'Boo yeah!'
                }
            });

            // Use this new renderer with the result
            renderArray[i].setDirections(result);
            // and start the next request
            nextRequest();
        }

    }

    function nextRequest(){
        // Increase the counter
        i++;
        // Make sure we are still waiting for a request
        if(i >= requestArray.length){
            // No more to do
            return;
        }
        // Submit another request
        submitRequest();
    }

    // This request is just to kick start the whole process
    submitRequest();
}

// Called Onload
function init() {

    var address = "320 Elizabeth St Midland, ON L4R 4L6";
    var geo = new google.maps.Geocoder;
    geo.geocode({'address':address},function(results, status){
        if (status == google.maps.GeocoderStatus.OK) {
            var latitude = results[0].geometry.location.lat();
            var longitude = results[0].geometry.location.lng();

            // Some basic map setup (from the API docs) 
            var mapOptions = {
                //center: new google.maps.LatLng(50.677965, -3.768841),
                center: new google.maps.LatLng(latitude, longitude),
                zoom: 10,
                mapTypeControl: true,
                streetViewControl: true,
                mapTypeId: google.maps.MapTypeId.ROADMAP,
                travelMode: google.maps.TravelMode.DRIVING,
                //unitSystem: google.maps.UnitSystem.IMPERIAL
                unitSystem: google.maps.UnitSystem.METRIC
            };

            map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

            var circle = {
                strokeColor: '#AA0000',
                strokeOpacity: 0.6,
                strokeWeight: 2,
                fillColor: '#CCCCCC',
                fillOpacity: 0.35,
                map: map,
                radius: 50000,
                center: new google.maps.LatLng(latitude, longitude)
            };

            var pickupSpot = new google.maps.Circle(circle);

            // Start the request making
            generateRequests()
        } else {
            alert("Geocode was not successful for the following reason: " + status);
        }
    });
}

// Get the ball rolling and trigger our init() on 'load'
google.maps.event.addDomListener(window, 'load', init);

</script>

</body>
</html>

I can't find anywhere online that teaches what I need. Can anyone help?

One solution:

  1. extract the polylines from each route
  2. process through each of the polylines, finding the closest point (using the straight line, "as the crow flies" distance)

// Use this new renderer with the result
renderArray[i].setDirections(result);
// and start the next request
var polyline = getPolyline(result);
var marker = new google.maps.Marker({
    position: getClosestPoint(referencePt, polyline),
    map: map,
    icon: iconArray[i]
});
nextRequest();

proof of concept fiddle

code snippet:

var referencePt = "TBD";

// Initialize some variables
var directionsService = new google.maps.DirectionsService();
var num, map, data;
var requestArray = [],
  renderArray = [];
var markerBounds = new google.maps.LatLngBounds();

// A JSON Array containing some people/routes and the destinations/stops
var jsonArray = {
  "Blue Run": ["300 University Ave, Plant 1 Belleville, ON K8N 5T7", "3900 West Hamlin Road Rochester Hills, MI 48309"],
  "Big Run": ["5811 - 99th Avenue Kenosha, WI 53144", "46600 Port St Plymouth, MI 48170"],
  "Slow Run": ["2155 North Talbot Road Windsor, ON N9A 6J3", "46600 Port St Plymouth, MI 48170", "2968 Waterview Rochester Hills, MI 48309", "4350 Campground Rd Louisville, KY 40216"]
}

// 16 Standard Colours for navigation polylines
var colourArray = ['navy', 'red', 'green', 'grey', 'fuchsia', 'black', 'white', 'lime', 'maroon', 'purple', 'aqua', 'silver', 'olive', 'blue', 'yellow', 'teal'];

var iconArray = [
  "http://maps.google.com/mapfiles/ms/icons/blue.png",
  "http://maps.google.com/mapfiles/ms/icons/red.png",
  "http://maps.google.com/mapfiles/ms/icons/green.png"
];

// Let's make an array of requests which will become individual polylines on the map.
function generateRequests() {

  requestArray = [];

  for (var route in jsonArray) {
    // This now deals with one of the people / routes

    // Somewhere to store the wayoints
    var waypts = [];

    // 'start' and 'finish' will be the routes origin and destination
    var start, finish

    // lastpoint is used to ensure that duplicate waypoints are stripped
    var lastpoint

    data = jsonArray[route]

    limit = data.length
    for (var waypoint = 0; waypoint < limit; waypoint++) {
      if (data[waypoint] === lastpoint) {
        // Duplicate of of the last waypoint - don't bother
        continue;
      }

      // Prepare the lastpoint for the next loop
      lastpoint = data[waypoint]

      // Add this to waypoint to the array for making the request
      waypts.push({
        location: data[waypoint],
        stopover: true
      });
    }

    // Grab the first waypoint for the 'start' location
    start = (waypts.shift()).location;
    // Grab the last waypoint for use as a 'finish' location
    finish = waypts.pop();
    if (finish === undefined) {
      // Unless there was no finish location for some reason?
      finish = start;
    } else {
      finish = finish.location;
    }

    // Let's create the Google Maps request object
    var request = {
      origin: start,
      destination: finish,
      waypoints: waypts,
      travelMode: google.maps.TravelMode.DRIVING
    };

    // and save it in our requestArray
    requestArray.push({
      "route": route,
      "request": request
    });
  }

  processRequests();
}

function processRequests() {

  // Counter to track request submission and process one at a time;
  var i = 0;

  // Used to submit the request 'i'
  function submitRequest() {
    directionsService.route(requestArray[i].request, directionResults);
  }

  // Used as callback for the above request for current 'i'
  function directionResults(result, status) {
    if (status == google.maps.DirectionsStatus.OK) {

      // Create a unique DirectionsRenderer 'i'
      renderArray[i] = new google.maps.DirectionsRenderer();
      renderArray[i].setMap(map);

      // Some unique options from the colorArray so we can see the routes
      renderArray[i].setOptions({
        preserveViewport: true,
        suppressInfoWindows: true,
        polylineOptions: {
          strokeWeight: 4,
          strokeOpacity: 0.8,
          strokeColor: colourArray[i]
        },
        markerOptions: {
          icon: {
            path: google.maps.SymbolPath.BACKWARD_CLOSED_ARROW,
            scale: 4,
            strokeColor: colourArray[i]
          },
          clickable: true,
          title: 'Boo yeah!'
        }
      });

      // Use this new renderer with the result
      renderArray[i].setDirections(result);
      // and start the next request
      var polyline = getPolyline(result);
      var marker = new google.maps.Marker({
        position: getClosestPoint(referencePt, polyline),
        map: map,
        icon: iconArray[i]
      });
      markerBounds.extend(marker.getPosition());
      nextRequest();
    }

  }

  function nextRequest() {
    // Increase the counter
    i++;
    // Make sure we are still waiting for a request
    if (i >= requestArray.length) {
      map.fitBounds(markerBounds);
      // No more to do
      return;
    }
    // Submit another request
    submitRequest();
  }

  // This request is just to kick start the whole process
  submitRequest();
}

function getPolyline(result) {
  var polyline = new google.maps.Polyline({
    path: []
  });
  var path = result.routes[0].overview_path;
  var legs = result.routes[0].legs;
  for (i = 0; i < legs.length; i++) {
    var steps = legs[i].steps;
    for (j = 0; j < steps.length; j++) {
      var nextSegment = steps[j].path;
      for (k = 0; k < nextSegment.length; k++) {
        polyline.getPath().push(nextSegment[k]);
      }
    }
  }
  return polyline;
}

function getClosestPoint(point, polyline) {
  var closestDistance = Number.MAX_VALUE;
  var closestPt;
  for (var i = 0; i < polyline.getPath().getLength(); i++) {
    var distance = google.maps.geometry.spherical.computeDistanceBetween(point, polyline.getPath().getAt(i));
    if (distance < closestDistance) {
      closestDistance = distance;
      closestPt = polyline.getPath().getAt(i);
    }
  }
  return closestPt;
}

// Called Onload
function init() {

  var address = "320 Elizabeth St Midland, ON L4R 4L6";
  var geo = new google.maps.Geocoder;
  geo.geocode({
    'address': address
  }, function(results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
      var latitude = results[0].geometry.location.lat();
      var longitude = results[0].geometry.location.lng();

      // Some basic map setup (from the API docs) 
      var mapOptions = {
        //center: new google.maps.LatLng(50.677965, -3.768841),
        center: new google.maps.LatLng(latitude, longitude),
        zoom: 10,
        mapTypeControl: true,
        streetViewControl: true,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        travelMode: google.maps.TravelMode.DRIVING,
        //unitSystem: google.maps.UnitSystem.IMPERIAL
        unitSystem: google.maps.UnitSystem.METRIC
      };

      map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

      var circle = {
        strokeColor: '#AA0000',
        strokeOpacity: 0.6,
        strokeWeight: 2,
        fillColor: '#CCCCCC',
        fillOpacity: 0.35,
        map: map,
        radius: 50000,
        center: new google.maps.LatLng(latitude, longitude)
      };
      referencePt = mapOptions.center;

      var pickupSpot = new google.maps.Circle(circle);

      // Start the request making
      generateRequests()
    } else {
      alert("Geocode was not successful for the following reason: " + status);
    }
  });
}

// Get the ball rolling and trigger our init() on 'load'
google.maps.event.addDomListener(window, 'load', init);

html,
body,
#map-canvas {
  height: 100%;
  margin: 0px;
  padding: 0px
}
#map-canvas {
  float: left;
  width: 70%;
  height: 100%;
}
#panel {
  position: absolute;
  top: 5px;
  left: 50%;
  margin-left: -180px;
  z-index: 5;
  background-color: #fff;
  padding: 5px;
  border: 1px solid #999;
}
#control_panel {
  float: right;
  width: 30%;
  text-align: left;
  padding-top: 20px;
}

<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<div id="map-canvas"></div>
<div id="control_panel">
  <div class="container" style="width:auto;">
    <h1>Trips:</h1>

    <div class="panel panel-default">
      <div class="panel-heading">
        <h3 class="panel-title">Blue Run</h3>

      </div>
      <div class="panel-body">
        <ol>
          <li><strong>Autosystems (University)</strong>
            <br />300 University Ave, Plant 1 Belleville, ON K8N 5T7</li>
          <li><strong>Fanuc America</strong>
            <br />3900 West Hamlin Road Rochester Hills, MI 48309</li>
        </ol>
      </div>
    </div>
    <div class="panel panel-default">
      <div class="panel-heading">
        <h3 class="panel-title">Big Run</h3>

      </div>
      <div class="panel-body">
        <ol>
          <li><strong>Asyst Technologies</strong>
            <br />5811 - 99th Avenue Kenosha, WI 53144</li>
          <li><strong>Autosystems America Inc</strong>
            <br />46600 Port St Plymouth, MI 48170</li>
        </ol>
      </div>
    </div>
    <div class="panel panel-default">
      <div class="panel-heading">
        <h3 class="panel-title">Slow Run</h3>

      </div>
      <div class="panel-body">
        <ol>
          <li><strong>A B Automation</strong>
            <br />2155 North Talbot Road Windsor, ON N9A 6J3</li>
          <li><strong>Autosystems America Inc</strong>
            <br />46600 Port St Plymouth, MI 48170</li>
          <li><strong>Industrial Automation</strong>
            <br />2968 Waterview Rochester Hills, MI 48309</li>
          <li><strong>Arkema Inc.</strong>
            <br />4350 Campground Rd Louisville, KY 40216</li>
        </ol>
      </div>
    </div>
  </div>
</div>
<input type="hidden" name="lat" id="lat" value="" />
<input type="hidden" name="lng" id="lng" value="" />