Skip to content
Example transport requests
44 pallets · Weekly · Midlands DoverExample requestTemperature-controlled · Daily · Avonmouth ScotlandExample requestFull load (FTL) · Multiple weekly · Felixstowe Golden TriangleExample request26 pallets · Ongoing contract · Manchester LondonExample requestChilled · Daily · Southampton North WestExample requestBonded freight · Weekly · Dover DaventryExample request12 pallets · One-off · Bristol South EastExample request2 x artic · Multiple weekly · Magna Park Belfast / NIExample requestAmbient palletised · Ongoing contract · Birmingham YorkshireExample requestHalf load (LTL) · Weekly · Plymouth South WestExample requestFull load (FTL) · Seasonal · Felixstowe ScotlandExample requestTemperature-controlled · Multiple weekly · Avonmouth LondonExample request26 pallets · Daily · Leeds South EastExample requestContainer haulage · Ongoing contract · Felixstowe MidlandsExample request

Multi Drop Route Planner UK

This multi drop route planner finds an efficient visiting order for up to 12 UK postcodes. It is built for delivery planners, hauliers and transport buyers, with total mileage, estimated HGV journey time and a numbered map.

  • No sign-up needed
  • Instant results in your browser
  • Published UK data
.ctool--multidrop{color:var(--cts-text);line-height:1.55} .ctool--multidrop p{margin:0 0 14px} .ctool--multidrop .ctool-how{font-size:.95rem;color:var(--cts-text-2);margin-bottom:22px} .ctool--multidrop .ctool-panel{background:transparent;border:0;border-radius:0;box-shadow:none;padding:0} .ctool--multidrop .ctool-field label{display:block;font-weight:700;font-size:.9rem;color:var(--cts-ink);margin-bottom:6px} .ctool--multidrop input[type=text],.ctool--multidrop input[type=number],.ctool--multidrop textarea{width:100%;box-sizing:border-box;border:1px solid var(--cts-line-2,#c9d2df);border-radius:10px;padding:11px 13px;font-size:16px;font-family:inherit;color:var(--cts-text);background:#fff} .ctool--multidrop input:focus,.ctool--multidrop textarea:focus{outline:2px solid var(--cts-brand);outline-offset:1px;border-color:var(--cts-brand)} .ctool--multidrop .ctool-start{margin-bottom:18px} .ctool--multidrop .ctool-dhead{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:8px} .ctool--multidrop .ctool-dhead b{font-size:.9rem;color:var(--cts-ink)} .ctool--multidrop .ctool-count{font-size:.85rem;color:var(--cts-muted,#67788c)} .ctool--multidrop .ctool-drop{display:flex;gap:8px;align-items:center;margin-bottom:8px} .ctool--multidrop .ctool-drop .n{width:26px;height:26px;flex:0 0 26px;border-radius:50%;background:var(--cts-brand-tint);color:var(--cts-ink-700);font-weight:700;font-size:.8rem;display:flex;align-items:center;justify-content:center} .ctool--multidrop .ctool-drop input{flex:1} .ctool--multidrop .ctool-drop button{flex:0 0 auto;width:38px;height:38px;border-radius:9px;border:1px solid var(--cts-line-2,#c9d2df);background:var(--cts-stone);color:var(--cts-ink);cursor:pointer;font-size:18px;font-family:inherit} .ctool--multidrop .ctool-drop button:hover{background:#fdecec;border-color:var(--cts-danger,#d23b3b);color:#8f1f1f} .ctool--multidrop .ctool-rowtools{display:flex;flex-wrap:wrap;gap:10px;margin-top:6px} .ctool--multidrop .ctool-btn,.ctool-cta .ctool-btn{display:inline-block;background:var(--cts-brand);color:#fff;border:0;border-radius:10px;font-weight:700;font-size:1rem;padding:12px 22px;cursor:pointer;font-family:inherit;text-decoration:none} .ctool--multidrop .ctool-btn:hover{background:var(--cts-brand-700,#0a4fd6)} .ctool--multidrop .ctool-btn--pdf{background:#fff;color:var(--cts-ink);border:1px solid var(--cts-line-2,#c9d2df);display:inline-flex;align-items:center;gap:.5rem;font-size:.95rem;padding:11px 18px} .ctool--multidrop .ctool-btn--pdf:hover{background:var(--cts-stone);border-color:var(--cts-brand);color:var(--cts-brand-700,#0a4fd6)} .ctool--multidrop .ctool-btn-ghost{background:transparent;color:var(--cts-brand);border:1px solid var(--cts-line-2,#c9d2df);padding:10px 16px;border-radius:10px;font-weight:700;cursor:pointer;font-family:inherit;font-size:.92rem} .ctool--multidrop .ctool-btn-ghost:hover{background:var(--cts-stone)} .ctool--multidrop .ctool-paste{margin-top:16px} .ctool--multidrop .ctool-paste textarea{min-height:78px;resize:vertical} .ctool--multidrop details.ctool-pastebox{border:0;padding:0} .ctool--multidrop details.ctool-pastebox>summary{font-size:.9rem;color:var(--cts-brand);font-weight:700;cursor:pointer;margin-bottom:8px} .ctool--multidrop .ctool-options{display:flex;flex-wrap:wrap;gap:14px 18px;align-items:end;margin-top:20px} .ctool--multidrop .ctool-opt{font-size:.9rem} .ctool--multidrop .ctool-opt label{display:block;font-weight:700;color:var(--cts-ink);margin-bottom:6px} .ctool--multidrop .ctool-opt input{width:110px} .ctool--multidrop .ctool-actions{display:flex;gap:10px;flex-wrap:wrap;margin-left:auto;align-items:center} .ctool--multidrop .ctool-msg{margin-top:14px;padding:12px 14px;border-radius:10px;font-size:.94rem;display:none} .ctool--multidrop .ctool-msg.is-err{display:block;background:#fdecec;border:1px solid var(--cts-danger,#d23b3b);color:#8f1f1f} .ctool--multidrop .ctool-msg.is-note{display:block;background:var(--cts-brand-tint);border:1px solid var(--cts-line);color:var(--cts-ink-700)} .ctool--multidrop #md-placeholder{min-height:440px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px} .ctool--multidrop #md-placeholder .ph-title{font-weight:700;color:var(--cts-ink);font-size:1.02rem} .ctool--multidrop .ctool-results{display:none} .ctool--multidrop .ctool-results.is-on{display:block} .ctool--multidrop .ctool-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-bottom:18px} .ctool--multidrop .ctool-stat{background:var(--cts-stone);border:1px solid var(--cts-line);border-radius:14px;padding:16px} .ctool--multidrop .ctool-stat .k{font-size:.82rem;font-weight:700;color:var(--cts-text-2);margin-bottom:6px} .ctool--multidrop .ctool-stat .v{font-size:1.6rem;font-weight:800;color:var(--cts-ink);line-height:1.1} .ctool--multidrop .ctool-stat .s{font-size:.85rem;color:var(--cts-muted,#67788c);margin-top:4px} .ctool--multidrop .ctool-map{height:460px;border-radius:14px;border:1px solid var(--cts-line);margin-bottom:18px;z-index:0} .ctool--multidrop .ctool-actionbar{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:14px} .ctool--multidrop .ctool-tablewrap{overflow-x:auto;border:1px solid var(--cts-line);border-radius:14px} .ctool--multidrop table{width:100%;border-collapse:collapse;font-size:.94rem;min-width:520px} .ctool--multidrop th,.ctool--multidrop td{text-align:left;padding:11px 14px;border-bottom:1px solid var(--cts-line)} .ctool--multidrop thead th{background:var(--cts-ink);color:#fff;font-weight:700} .ctool--multidrop tbody tr:last-child td{border-bottom:0} .ctool--multidrop tbody tr.is-start td{background:var(--cts-brand-tint)} .ctool--multidrop td.num,.ctool--multidrop th.num{text-align:right;font-variant-numeric:tabular-nums} .ctool--multidrop .stopn{display:inline-flex;width:24px;height:24px;border-radius:50%;background:var(--cts-brand);color:#fff;font-weight:700;font-size:.8rem;align-items:center;justify-content:center} .ctool--multidrop .stopn.s0{background:var(--cts-verified,#15A66B)} .ctool--multidrop .ctool-cap{font-size:.85rem;color:var(--cts-muted,#67788c);margin:8px 2px 0} .ctool--multidrop .ctool-pin{background:var(--cts-brand);color:#fff;border-radius:50% 50% 50% 0;transform:rotate(-45deg);width:26px;height:26px;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:.78rem;box-shadow:0 2px 6px rgba(0,0,0,.35);border:2px solid #fff} .ctool--multidrop .ctool-pin span{transform:rotate(45deg)} .ctool--multidrop .ctool-pin.s0{background:var(--cts-verified,#15A66B)} .ctool--multidrop .ctool-support h2{color:var(--cts-ink);margin-top:0} .ctool--multidrop .ctool-support__cols h2+p{margin-top:0} .ctool--multidrop details.ctool-faq{border:1px solid var(--cts-line);border-radius:12px;padding:2px 16px;margin-bottom:10px;background:#fff} .ctool--multidrop details.ctool-faq>summary{cursor:pointer;font-weight:700;padding:12px 0;color:var(--cts-ink)} .ctool-cta{background:var(--cts-ink);border-radius:16px;padding:30px 28px;margin-top:34px;color:#fff} .ctool-cta h2{color:#fff;margin:0 0 8px} .ctool-cta p{color:#d8e3f2;margin:0 0 18px;max-width:60ch} .ctool--multidrop .ctool-spin{display:inline-block;width:16px;height:16px;border:2px solid rgba(255,255,255,.5);border-top-color:#fff;border-radius:50%;animation:ctool-spin .7s linear infinite;vertical-align:-3px;margin-right:8px} @keyframes ctool-spin{to{transform:rotate(360deg)}} @media(max-width:640px){ .ctool--multidrop .ctool-stats{grid-template-columns:1fr} .ctool--multidrop .ctool-actions{margin-left:0;width:100%} .ctool--multidrop .ctool-actions .ctool-btn{flex:1} .ctool--multidrop .ctool-map{height:340px} .ctool--multidrop #md-placeholder{min-height:220px} }

How to use: enter your depot or start postcode, add each drop (or paste a list, one postcode per line), set your minutes per drop, then select Plan route. The tool orders the stops to cut the total distance.

Drop postcodes0 of 12
Or paste a list (one postcode per line)
Your planned round appears here Add your drops and select Plan route to see the optimised order, numbered map and mileage.
Total road distance
-
Drive plus drops time
-
HGV estimate, includes dwell
Stops planned
-
StopPostcodeAreaLegCumulative time

Cumulative time is the estimated HGV drive time to reach a stop plus the dwell time for it and all earlier stops. It excludes traffic, breaks and driver hours limits.

Methodology and assumptions

Every postcode is geocoded with postcodes.io, a free open service built on Ordnance Survey and Office for National Statistics data. Full postcodes use the /postcodes endpoint and outward-only codes (for example LS10) fall back to /outcodes, which returns the district centre, so those stops are placed at outward-area level.

The optimised visiting order, total distance, drive time and route line come from the public OSRM trip service, which solves the stop order using OpenStreetMap road data. We fix the first stop as your start postcode and let the engine choose the most efficient order for the rest without forcing a return to the depot. OSRM gives a car driving time; because heavy goods vehicles are slower, we apply a 0.85 speed factor, assuming an HGV averages 85 percent of car speed, and divide the OSRM time by 0.85 (about 18 percent longer). We then add your minutes-per-drop dwell time (default 15) for each stop to build the cumulative schedule.

If the trip service does not respond within 8 seconds, we fall back to a nearest-neighbour order computed in your browser from straight-line (haversine) distances, with leg distances multiplied by 1.25 to approximate road winding and drive time at an assumed 45 mph. This fallback is clearly labelled as an estimate and draws straight lines between stops rather than the true road route. The OSRM public demo server is provided for moderate use only, so please do not hammer it. Mapping and routing data are copyright OpenStreetMap contributors and served through OSRM. Assumptions current as of July 2026. This planner gives a planning-grade schedule, not a compliance record of driver hours.

Frequently asked questions

How does the multi-drop route planner order my stops?

It sends your start and drop postcodes to the OSRM trip service, which uses OpenStreetMap road data to find an efficient visiting order that keeps the first stop as your depot. The result is the sequence, total miles and drive time, shown as a numbered map and an ordered table.

How many drops can I plan at once?

Up to 12 delivery postcodes plus your start point. You can type them into rows or paste a list, one postcode per line. For larger rounds, split the day into two routes or contact CTS about a dedicated distribution plan.

Does it plan for a van or an HGV?

The drive time is an HGV estimate: we slow the car time OSRM returns to 85 percent of car speed. It suits both vans and lorries as a planning figure, though a light van on clear roads may be a little quicker.

What does minutes per drop mean?

It is the dwell time you expect at each stop for parking, unloading and paperwork. The default is 15 minutes. The tool adds it to the drive time so the cumulative column reflects a realistic round, not just moving time.

Can I copy the route to share with a driver?

Yes. Select Copy route order to put the ordered stop list on your clipboard, ready to paste into a message, run sheet or notes app.

Is the multi-drop route planner free?

Yes, it is free with no sign-up and runs in your browser using open UK postcode and OpenStreetMap data.

Turn an efficient round into the right delivery partner

Planning the order is the easy part. Running multi-drop rounds day in, day out needs the right fleet and licensed operator. Brief CTS on your delivery profile and we place it before vetted UK operators for dedicated distribution or full contract distribution. It is free and there is no obligation.

Request quotes
(function(){ var $=function(id){return document.getElementById(id);}; var MAX=12,UKGALLON=4.54609; var els={start:$('md-start'),drops:$('md-drops'),count:$('md-count'),add:$('md-add'),clear:$('md-clear'), paste:$('md-paste'),importBtn:$('md-import'),dwell:$('md-dwell'),go:$('md-go'),msg:$('md-msg'), placeholder:$('md-placeholder'), results:$('md-results'),miles:$('md-miles'),km:$('md-km'),time:$('md-time'),stops:$('md-stops'), source:$('md-source'),body:$('md-body'),copy:$('md-copy')}; var map=null,layer=null,lastOrder=null,lastCalc=null,geoCache={}; function norm(s){return (s||'').toUpperCase().replace(/s+/g,' ').trim();} function compact(s){return norm(s).replace(/s+/g,'');} function outward(s){var c=compact(s);if(c.length=MAX; els.add.style.opacity=rows.length>=MAX?'.5':'1'; } function addRow(val){ if(rowCount()>=MAX)return null; var row=document.createElement('div');row.className='ctool-drop'; row.innerHTML=''+ ''; var inp=row.querySelector('input');if(val)inp.value=val; row.querySelector('button').addEventListener('click',function(){ if(rowCount()<=1){inp.value='';renumber();return;} row.remove();renumber(); }); inp.addEventListener('keydown',function(e){if(e.key==='Enter'){e.preventDefault();run();}}); els.drops.appendChild(row);renumber();return inp; } function getDrops(){ var out=[];els.drops.querySelectorAll('.ctool-drop input').forEach(function(i){ if(compact(i.value))out.push(i.value.trim());}); return out; } function fetchJSON(url,ms){ var ctrl=new AbortController();var timer=setTimeout(function(){ctrl.abort();},ms||8000); return fetch(url,{signal:ctrl.signal}).then(function(r){clearTimeout(timer);return r.json();}) .catch(function(e){clearTimeout(timer);throw e;}); } function geocode(raw){ var key=compact(raw);if(!key)return Promise.reject(new Error('empty')); if(geoCache[key])return Promise.resolve(geoCache[key]); return fetchJSON('https://api.postcodes.io/postcodes/'+encodeURIComponent(key)).then(function(j){ if(j&&j.status===200&&j.result){ var r=j.result;var g={lat:r.latitude,lon:r.longitude,label:r.postcode,area:r.admin_district||r.region||'',approx:false}; geoCache[key]=g;return g; } throw new Error('not-full'); }).catch(function(){ var oc=outward(raw); return fetchJSON('https://api.postcodes.io/outcodes/'+encodeURIComponent(oc)).then(function(j){ if(j&&j.status===200&&j.result&&j.result.latitude!=null){ var r=j.result;var area=(r.admin_district&&r.admin_district[0])||(r.region&&r.region[0])||''; var g={lat:r.latitude,lon:r.longitude,label:oc,area:area,approx:true};geoCache[key]=g;return g; } throw new Error('bad'); }); }); } function haversine(a,b){ var R=6371,rad=Math.PI/180; var dLat=(b.lat-a.lat)*rad,dLon=(b.lon-a.lon)*rad,la1=a.lat*rad,la2=b.lat*rad; var h=Math.sin(dLat/2)*Math.sin(dLat/2)+Math.cos(la1)*Math.cos(la2)*Math.sin(dLon/2)*Math.sin(dLon/2); return 2*R*Math.asin(Math.min(1,Math.sqrt(h))); } function fmtTime(mins){mins=Math.round(mins);var h=Math.floor(mins/60),m=mins%60;if(h<=0)return m+' min';return h+' h '+(m=100?Math.round(mi).toLocaleString('en-GB'):mi.toFixed(1);} function ensureMap(){ if(map)return; map=L.map('md-map',{scrollWheelZoom:false}).setView([54,-2.5],5); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{maxZoom:19, attribution:'© OpenStreetMap contributors'}).addTo(map); } function drawMap(orderedPts,line,dashed){ ensureMap(); if(layer)map.removeLayer(layer); layer=L.layerGroup().addTo(map); orderedPts.forEach(function(p,i){ var html='
'+(i===0?'S':i)+'
'; L.marker([p.lat,p.lon],{icon:L.divIcon({className:'',html:html,iconSize:[26,26],iconAnchor:[13,26]})}) .bindTooltip((i===0?'Start: ':'Stop '+i+': ')+p.label,{}).addTo(layer); }); var latlngs=line?line.map(function(c){return [c[1],c[0]];}):orderedPts.map(function(p){return [p.lat,p.lon];}); var poly=L.polyline(latlngs,{color:'#1065FF',weight:5,opacity:.85,dashArray:dashed?'8,10':null}).addTo(layer); map.fitBounds(poly.getBounds().pad(0.15)); setTimeout(function(){map.invalidateSize();},60); } function nearestNeighbour(pts){ var n=pts.length,used=new Array(n).fill(false),order=[0];used[0]=true;var cur=0; for(var k=1;k<n;k++){ var best=-1,bd=Infinity; for(var j=0;j<n;j++){if(!used[j]){var d=haversine(pts[cur],pts[j]);if(d<bd){bd=d;best=j;}}} order.push(best);used[best]=true;cur=best; } return order; } function setBusy(on){els.go.disabled=on;els.go.innerHTML=on?'Planning':'Plan route';} function run(){ clearMsg(); var startRaw=els.start.value; if(!compact(startRaw)){showMsg('Please enter a start postcode.','err');return;} var drops=getDrops(); if(drops.length<1){showMsg('Add at least one drop postcode.','err');return;} // dedupe exact repeats but keep first occurrence var seen={},uniq=[];drops.forEach(function(d){var k=compact(d);if(!seen[k]){seen[k]=1;uniq.push(d);}}); var dropped=drops.length-uniq.length; drops=uniq; setBusy(true); var all=[startRaw].concat(drops); Promise.all(all.map(function(pc){return geocode(pc).then(function(g){return g;},function(){return {bad:pc};});})) .then(function(pts){ var bad=pts.filter(function(p){return p.bad;}); if(bad.length){throw {kind:'geo',list:bad.map(function(b){return b.bad;})};} var coordStr=pts.map(function(p){return p.lon+','+p.lat;}).join(';'); var url='https://router.project-osrm.org/trip/v1/driving/'+coordStr+'?roundtrip=false&source=first&overview=full&geometries=geojson'; return fetchJSON(url).then(function(j){ if(!j||j.code!=='Ok'||!j.trips||!j.trips.length)throw new Error('trip'); var trip=j.trips[0]; // build ordered input index list from waypoint_index var orderByPos=[];j.waypoints.forEach(function(w,inputIdx){orderByPos[w.waypoint_index]=inputIdx;}); var orderedPts=orderByPos.map(function(idx){return pts[idx];}); var legMiles=trip.legs.map(function(l){return l.distance/1609.344;}); var legMin=trip.legs.map(function(l){return (l.duration/60)/0.85;}); render(orderedPts,legMiles,legMin,trip.distance/1609.344,trip.geometry.coordinates,false,dropped); }); }).catch(function(err){ if(err&&err.kind==='geo'){ showMsg('We could not find: '+err.list.join(', ')+'. Check for typos or use the outward code only.','err'); els.results.classList.remove('is-on');setBusy(false);return; } // OSRM fallback: nearest-neighbour on already-geocoded points Promise.all(all.map(function(pc){return geocode(pc);})).then(function(pts){ var order=nearestNeighbour(pts); var orderedPts=order.map(function(i){return pts[i];}); var legMiles=[],legMin=[],total=0; for(var i=0;i=0))dwell=15; els.placeholder.style.display='none'; els.results.classList.add('is-on'); var totalDriveMin=legMin.reduce(function(a,b){return a+b;},0); var dropCount=orderedPts.length-1; var totalMin=totalDriveMin+dwell*dropCount; var milesStr=fmtMiles(totalMiles)+' mi'; var kmStr=(totalMiles*1.609344).toFixed(1)+' km'+(est?' (estimate)':''); var timeStr=fmtTime(totalMin)+(est?'*':''); els.miles.innerHTML=fmtMiles(totalMiles)+' mi'; els.km.textContent=kmStr; els.time.textContent=timeStr; els.stops.textContent=dropCount; var approx=orderedPts.some(function(p){return p.approx;}); var methodStr=est?'Nearest-neighbour estimate':(approx?'OSRM optimised trip (outward-level stops)':'OSRM optimised trip'); els.source.textContent=methodStr; var rows='',cum=0,pdfRows=[]; orderedPts.forEach(function(p,i){ if(i===0){ rows+='S'+esc(p.label)+''+esc(p.area||'Start')+'-0 min'; pdfRows.push(['S',p.label,p.area||'Start','-','0 min']); }else{ cum+=legMin[i-1]+dwell; rows+=''+i+''+esc(p.label)+''+esc(p.area||'')+''+legMiles[i-1].toFixed(1)+' mi'+fmtTime(cum)+''; pdfRows.push([String(i),p.label,p.area||'',legMiles[i-1].toFixed(1)+' mi',fmtTime(cum)]); } }); els.body.innerHTML=rows; lastOrder=orderedPts; lastCalc={ start:orderedPts[0].label, drops:dropCount, dwell:dwell, method:methodStr, miles:milesStr, km:(totalMiles*1.609344).toFixed(1)+' km'+(est?' (estimate)':''), time:fmtTime(totalMin)+(est?' (estimate)':''), rows:pdfRows }; drawMap(orderedPts,line,est); if(dropped>0)appendNote(dropped+' duplicate postcode'+(dropped>1?'s were':' was')+' removed.'); els.results.scrollIntoView({behavior:'smooth',block:'nearest'}); } function appendNote(t){ if(els.msg.className.indexOf('is-')<0){showMsg(t,'note');} else{els.msg.textContent=els.msg.textContent+' '+t;} } function esc(s){return (s+'').replace(/[&"]/g,function(c){return {'&':'&','':'>','"':'"'}[c];});} els.add.addEventListener('click',function(){var i=addRow('');if(i)i.focus();}); els.clear.addEventListener('click',function(){els.drops.innerHTML='';addRow('');addRow('');clearMsg();}); els.go.addEventListener('click',run); els.start.addEventListener('keydown',function(e){if(e.key==='Enter')run();}); els.dwell.addEventListener('input',function(){if(lastOrder)run();}); els.importBtn.addEventListener('click',function(){ var lines=(els.paste.value||'').split(/[n,;]+/).map(function(s){return s.trim();}).filter(function(s){return s;}); if(!lines.length){showMsg('Paste one postcode per line first.','err');return;} els.drops.innerHTML=''; var added=0,skipped=0; lines.forEach(function(l){if(added<MAX){if(addRow(l))added++;}else skipped++;}); if(added0)showMsg('Imported the first '+MAX+' postcodes. '+skipped+' more were not added (12 drop limit).','note'); }); els.copy.addEventListener('click',function(){ if(!lastOrder)return; var lines=lastOrder.map(function(p,i){return (i===0?'Start: ':i+'. ')+p.label+(p.area?' ('+p.area+')':'');}); var text='Route order ('+(lastOrder.length-1)+' drops):n'+lines.join('n'); var done=function(){var o=els.copy.textContent;els.copy.textContent='Copied';setTimeout(function(){els.copy.textContent=o;},1600);}; if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(text).then(done,function(){fallbackCopy(text,done);});} else fallbackCopy(text,done); }); function fallbackCopy(text,cb){ var ta=document.createElement('textarea');ta.value=text;ta.style.position='fixed';ta.style.opacity='0'; document.body.appendChild(ta);ta.select();try{document.execCommand('copy');cb();}catch(e){}document.body.removeChild(ta); } window.ctsToolPDF={ title:'Multi Drop Route Planner UK', subtitle:'Free multi drop route planner for up to 12 UK postcodes. Optimise stop order, then see total miles, estimated HGV journey time and a numbered delivery map.', filename:'multi-drop-route-planner', getSections:function(){ if(!lastCalc)return null; return [ {h:'Inputs'}, {kv:[ ['Start postcode (depot)',lastCalc.start], ['Drops planned',String(lastCalc.drops)], ['Minutes per drop',String(lastCalc.dwell)], ['Method',lastCalc.method] ]}, {h:'Results'}, {kv:[ ['Total road distance',lastCalc.miles], ['Equivalent',lastCalc.km], ['Drive plus drops time',lastCalc.time], ['Stops planned',String(lastCalc.drops)] ]}, {h:'Optimised drop order'}, {table:{head:['Stop','Postcode','Area','Leg','Cumulative time'],rows:lastCalc.rows}}, {note:'Drive times are an HGV estimate (OSRM car time divided by 0.85) plus your minutes-per-drop dwell, with the visiting order solved by the OSRM trip service on OpenStreetMap road data. Assumptions current as of July 2026.'} ]; } }; // seed with a demo round ['M1 1AE','S1 2HH','NG1 5DT'].forEach(function(v){addRow(v);}); })();

Get transport quotes in minutes

Free for your business. No obligation at any point.

What are you moving?
Where is it moving?

Outward code is enough. Multiple drops? Add them at the end.

How often, and when?
Frequency
When do you need it?
Where should the quotes go?

Your request goes only to matched operators. It is never posted publicly or sold on.

Trusted contract transport matchmaking