2011-04-15 11 views
19

के साथ ग्रेडियंट पॉलीलाइन मैं ओवरले (एमकेओवरले) का उपयोग कर एमकेमैप व्यू पर एक मार्ग का पता लगाने की कोशिश कर रहा हूं। हालांकि, वर्तमान गति के आधार पर, यदि रंग बदल रहा है, तो मार्ग का पता लगाने के दौरान नाइके ऐप की तरह ढाल के साथ कुछ करना चाहते हैं (उदाहरण के लिए, यदि उपयोगकर्ता 65 मील प्रति घंटे से 30 मील प्रति घंटे तक चला रहा है तो हरे से नारंगी तक)। मैंमैपकिट आईओएस

// Create a c array of points. 
MKMapPoint *pointsArray = malloc(sizeof(CLLocationCoordinate2D) * 2); 

// Create 2 points. 
MKMapPoint startPoint = MKMapPointForCoordinate(CLLocationCoordinate2DMake(oldLatitude, oldLongitude)); 
MKMapPoint endPoint = MKMapPointForCoordinate(CLLocationCoordinate2DMake(newLatitude, newLongitude)); 

// Fill the array. 
pointsArray[0] = startPoint; 
pointsArray[1] = endPoint; 

// Erase polyline and polyline view if not nil. 
if (self.routeLine != nil) 
    self.routeLine = nil; 

if (self.routeLineView != nil) 
    self.routeLineView = nil; 

// Create the polyline based on the array of points. 
self.routeLine = [MKPolyline polylineWithPoints:pointsArray count:2]; 

// Add overlay to map. 
[self.mapView addOverlay:self.routeLine]; 

// clear the memory allocated earlier for the points. 
free(pointsArray); 

// Save old coordinates. 
oldLatitude = newLatitude; 
oldLongitude = newLongitude; 

असल:

gradient overlay image

इसलिए हर 20 मीटर की दूरी, मैं पुराने से एक ओवरले के नए निर्देशांक का उपयोग कर जोड़ने:

यहाँ मैं क्या चाहते का एक स्क्रीनशॉट बहुत सारे ओवरले जोड़ना। तब मैं इस छोटे से लाइन ड्राइंग पर ढाल बनाना चाहेंगे, तो मैं ओवरले प्रतिनिधि में ऐसा करने की कोशिश कर रहा हूँ:

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay { 
    MKOverlayView* overlayView = nil; 

    if(overlay == self.routeLine) { 
     // If we have not yet created an overlay view for this overlay, create it now. 
     if(self.routeLineView == nil) { 
      self.routeLineView = [[[MKPolylineView alloc] initWithPolyline:self.routeLine] autorelease]; 

      if (speedMPH < 25.0) { 
       self.routeLineView.fillColor = [UIColor redColor]; 
       self.routeLineView.strokeColor = [UIColor redColor]; 
      } 
      else if (speedMPH >= 25.0 && speedMPH < 50.0) { 
       self.routeLineView.fillColor = [UIColor orangeColor]; 
       self.routeLineView.strokeColor = [UIColor orangeColor]; 
      } 
      else { 
       self.routeLineView.fillColor = [UIColor greenColor]; 
       self.routeLineView.strokeColor = [UIColor greenColor]; 
      } 

      // Size of the trace. 
      self.routeLineView.lineWidth = routeLineWidth; 

      // Add gradient if color changed. 
      if (oldColor != self.routeLineView.fillColor) { 
       CAGradientLayer *gradient = [CAGradientLayer layer]; 
        gradient.frame = self.routeLineView.bounds; 
        gradient.colors = [NSArray arrayWithObjects:(id)[oldColor CGColor], (id)[self.routeLineView.fillColor CGColor], nil]; 
        [self.routeLineView.layer insertSublayer:gradient atIndex:0]; 
      } 

      // Record old color for gradient. 
      if (speedMPH < 25.0) 
       oldColor = [UIColor redColor]; 
      else if (speedMPH >= 25.0 && speedMPH < 50.0) 
       oldColor = [UIColor orangeColor]; 
      else 
       oldColor = [UIColor greenColor]; 
     } 

     overlayView = self.routeLineView; 
    } 

    return overlayView; 
} 

मैं ढाल इस तरह से जोड़ने के लिए कोशिश कर रहा हूँ, लेकिन मुझे लगता है कि यह है ऐसा करने का तरीका नहीं है क्योंकि मैं इसे काम नहीं कर सकता।

मैं उपयोगकर्ता के स्थान (स्थान वस्तु के प्रतिनिधि में) या प्रत्येक 20 मीटर से ऊपर के अपडेट पर हर बार मार्ग का पता लगा सकता हूं।

क्या आप कृपया मुझे उस पर मदद कर सकते हैं, मुझे सुझाव दे रहे हैं! धन्यवाद!

+1

रूटलाइन और रूटलाइन व्यू कैसे घोषित किया गया है? उपरोक्त कोड किस वर्ग में है? "यह काम नहीं कर सकता" - क्या होता है? – Rayfleck

+0

मुझे केवल उन ग्रेडियेंट्स को नहीं दिख रहा है जिन्हें मैं अपने ओवरले व्यू में जोड़ रहा हूं। 'एमकेपोलीलाइन * रूटलाइन;' और 'एमकेपोलीलाइन व्यू * रूटलाइन व्यू;', फिर हर 20 मीटर मैं एक नया बना देता हूं और इसे ओवरले के रूप में जोड़ता हूं। और ऊपर MKMapView प्रतिनिधि समारोह में मैं मानदंडों के आधार पर दृश्य बनाता हूं और इसमें ढाल जोड़ने की कोशिश करता हूं। – Dachmt

उत्तर

2

मुझे लगता है कि रेखा रेखाचित्र दृश्य में आपके drawRect ढाल की सेटिंग गुम है। ओवरले के लिए एक अलग धागे पर ड्राइंग हो सकती है। कृपया कोड पोस्ट करें।

+0

कृपया मेरे पोस्ट में उपरोक्त कोड देखें, मैंने इसे अपडेट किया है। मेरे पास एक ऐसा फ़ंक्शन है जो प्रत्येक 20 मीटर बिंदु बी से बिंदु बी को ओवरले जोड़ता है, और फिर जब मैं मानचित्र दृश्य प्रतिनिधि में ओवरले व्यू बनाता हूं तो मैं ढाल परत जोड़ने की कोशिश कर रहा हूं। – Dachmt

+0

आपका तर्क गलत लगता है। आप इस तरह ओवरले में ढाल परतों को जोड़ नहीं सकते हैं। इसके बजाय आपको अलग-अलग रंगों के अलग-अलग हिस्सों के साथ पूरे पथ को बनाने और खींचने का तरीका होना चाहिए। डब्ल्यूडब्ल्यूडीसी 2010 नमूना कोड ("ब्रेडक्रंब") यह प्रदर्शित करता है। आपका वर्तमान दृष्टिकोण काम नहीं कर सकता क्योंकि आप केवल पहली बार नए sublayers के रूप में पथ खंड जोड़ रहे हैं। लेकिन इससे समय के साथ परत पेड़ बहुत बड़ा हो जाएगा। आपको एक परत में पूरा पथ खींचने में सक्षम होना चाहिए। – Cocoanetics

+0

ठीक है, धन्यवाद @ कोकोनेटिक्स मैं इसे देख लूंगा और आपको अपडेट रखूंगा! – Dachmt

13

विचार मैं आया था में से एक हर बार जब drawMapRect विधि बुलाया गया, ढाल के साथ एक CGPath और स्ट्रोक उसे बनाने के लिए के बाद से MKPolylineView iOS7 में MKPlolylineRenderer द्वारा बदल दिया जाता है।

मैं एक MKOverlayPathRenderer उपवर्गीकरण से यह लागू करने की कोशिश की, लेकिन मैं व्यक्तिगत CGPath बाहर लेने में विफल रहा है, तो मैं एक रहस्यमय विधि -(void) strokePath:(CGPathRef)path inContext:(CGContextRef)context जो मैं क्या जरूरत है की तरह लगता है नामित लगता है, लेकिन अगर आप कॉल नहीं करते यह नहीं कहा जा जाएगा सुपर विधि जब आप अपने drawMapRect को ओवरराइड करते हैं।

जो मैं अभी के लिए काम कर रहा हूं।

मैं कोशिश करूँगा इसलिए यदि मैं कुछ काम करता हूं तो मैं वापस आऊंगा और उत्तर अपडेट करूँगा।

========= अद्यतन ================================== ==============

enter image description here

तो वह यह है कि मैं क्या बाहर काम कर रहा हूँ इन दिनों, मैं लगभग मूल विचार ऊपर उल्लेख लागू किया लेकिन हां, मैं अभी भी नहीं चुन सकते विशिष्ट mapRect के अनुसार एक व्यक्तिगत पथ को बाहर निकालें, इसलिए मैं केवल उसी पथ पर ढाल के साथ सभी पथ खींचता हूं जब सभी पथों की बाउंडिंगबॉक्स वर्तमान मानचित्र के साथ छेड़छाड़ करता है। खराब चाल, लेकिन अभी के लिए काम करते हैं।

में -(void) drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context विधि में वर्ग प्रस्तुत करना, मैं यह कर:

CGMutablePathRef fullPath = CGPathCreateMutable(); 
BOOL pathIsEmpty = YES; 

//merging all the points as entire path 
for (int i=0;i< polyline.pointCount;i++){ 
    CGPoint point = [self pointForMapPoint:polyline.points[i]]; 
    if (pathIsEmpty){ 
     CGPathMoveToPoint(fullPath, nil, point.x, point.y); 
     pathIsEmpty = NO; 
    } else { 
     CGPathAddLineToPoint(fullPath, nil, point.x, point.y); 
    } 
} 

//get bounding box out of entire path. 
CGRect pointsRect = CGPathGetBoundingBox(fullPath); 
CGRect mapRectCG = [self rectForMapRect:mapRect]; 
//stop any drawing logic, cuz there is no path in current rect. 
if (!CGRectIntersectsRect(pointsRect, mapRectCG))return; 

तो मैं बात करके पूरे पथ बिंदु विभाजित व्यक्तिगत रूप से अपनी ढाल आकर्षित करने के लिए। ध्यान दें कि hues सरणी जिसमें स्थान की प्रत्येक वेग मैपिंग है।

for (int i=0;i< polyline.pointCount;i++){ 
    CGMutablePathRef path = CGPathCreateMutable(); 
    CGPoint point = [self pointForMapPoint:polyline.points[i]]; 
    ccolor = [UIColor colorWithHue:hues[i] saturation:1.0f brightness:1.0f alpha:1.0f]; 
    if (i==0){ 
     CGPathMoveToPoint(path, nil, point.x, point.y); 
    } else { 
     CGPoint prevPoint = [self pointForMapPoint:polyline.points[i-1]]; 
     CGPathMoveToPoint(path, nil, prevPoint.x, prevPoint.y); 
     CGPathAddLineToPoint(path, nil, point.x, point.y); 
     CGFloat pc_r,pc_g,pc_b,pc_a, 
     cc_r,cc_g,cc_b,cc_a; 
     [pcolor getRed:&pc_r green:&pc_g blue:&pc_b alpha:&pc_a]; 
     [ccolor getRed:&cc_r green:&cc_g blue:&cc_b alpha:&cc_a]; 
     CGFloat gradientColors[8] = {pc_r,pc_g,pc_b,pc_a, 
            cc_r,cc_g,cc_b,cc_a}; 

     CGFloat gradientLocation[2] = {0,1}; 
     CGContextSaveGState(context); 
     CGFloat lineWidth = CGContextConvertSizeToUserSpace(context, (CGSize){self.lineWidth,self.lineWidth}).width; 
     CGPathRef pathToFill = CGPathCreateCopyByStrokingPath(path, NULL, lineWidth, self.lineCap, self.lineJoin, self.miterLimit); 
     CGContextAddPath(context, pathToFill); 
     CGContextClip(context);//<--clip your context after you SAVE it, important! 
     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
     CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, gradientColors, gradientLocation, 2); 
     CGColorSpaceRelease(colorSpace); 
     CGPoint gradientStart = prevPoint; 
     CGPoint gradientEnd = point; 
     CGContextDrawLinearGradient(context, gradient, gradientStart, gradientEnd, kCGGradientDrawsAfterEndLocation); 
     CGGradientRelease(gradient); 
     CGContextRestoreGState(context);//<--Don't forget to restore your context. 
    } 
    pcolor = [UIColor colorWithCGColor:ccolor.CGColor]; 
} 

है यही कारण है कि सभी मुख्य ड्राइंग विधि और निश्चित रूप से आप points, velocity आपके ओवरले कक्षा में की जरूरत है और उन्हें CLLocationManager साथ खाते हैं।

अंतिम बिंदु यह है कि hue वेग से बाहर मूल्य कैसे प्राप्त करें, ठीक है, मैंने पाया कि यदि 0.03 ~ 0.3 से लेकर रंग लाल से हरे रंग का प्रतिनिधित्व करता है, तो मैं कुछ आनुपातिक रूप से रंग और वेग के लिए मानचित्रण करता हूं।

पिछले के पिछले है, यहाँ आप कर रहे हैं इस इस डेमो का पूरा स्रोत है: https://github.com/wdanxna/GradientPolyline

अगर लाइन आप आकर्षित नहीं देख सकते हैं

घबराओ मत, मैं सिर्फ मेरी स्थिति नक्शे पर क्षेत्र की स्थिति :)

+0

बस अपना जवाब देखा। मुझे लगता है कि यह वही है जो मुझे इस प्रश्न में हासिल करने की आवश्यकता है: http://stackoverflow.com/questions/20247313/gradient-along-mkpolylineview-mkpolylinerenderer। असल में, अगर मैं सही ढंग से समझता हूं, तो आप सेगमेंट द्वारा मैन्युअल रूप से सेगमेंट को रूट करते हैं और प्रत्येक बार क्लिपिंग करके वर्तमान में जोड़ा गया एक ग्रेडियेंट लागू करते हैं। क्या यह इष्टतम/तेज है? – Templar

+0

सबसे पहले, मैंने पूरे पथ को एक ढाल ऑब्जेक्ट के साथ खींचने की कोशिश की जिसमें मेरे सभी ग्रेड मूल्यों को 'gradientColors' में आवश्यक है और प्रत्येक रंग मान मेरे 'gradientLocation' में एक स्थान मान मैपिंग कर रहा है। मैंने सोचा कि काम करना चाहिए लेकिन यह नहीं (अजीब)। और दस्तावेज कहता है कि हमें किसी भी चीज़ को वर्तमान मैपरेक्ट से बाहर नहीं खींचा जाना चाहिए, ऐसा लगता है कि एक बार पूरा पथ नहीं है क्योंकि सभी विकल्प एक विकल्प नहीं है? तो मुझे लगता है कि इसे खंड में विभाजित करना सबसे आसान तरीका है ...इष्टतम के बारे में बात करते हुए, यह मेरे आईफोन में ठीक चल रहा है :) लेकिन अभी भी कुछ सुधार करने के लिए कुछ है, जैसे: केवल वर्तमान मैपरेक्ट के साथ छेड़छाड़ वाली रेखाएं खींचना। – wdanxna

+0

मैंने अपनी सामग्री को आपके कोड और जिथब उदाहरण के आधार पर लागू किया और बिल्कुल शानदार काम करता है। केवल परिवर्तन जो मैं सुझाव दूंगा वह पथ को सीधे init में तैयार करना है और केवल 'drawRect' में उपयोग करें या' CGRect pointsR = [self rectForMapRect: polyline.boundingMapRect] का उपयोग करें; 'और सीजीआरईटीकॉन्टेंस के लिए भी जांचें, न केवल छेड़छाड़ के लिए । मेरा सवाल अभी भी अनुत्तरित नहीं है और इसका एक उपहार है। आप वहां अपना उत्तर पोस्ट कर सकते हैं और मैं इसे खुशी से स्वीकार करूंगा, इससे मुझे बहुत मदद मिली :) – Templar

संबंधित मुद्दे