Display traceroute results on a world map.

def world_trace(self):
        """Display traceroute results on a world map."""

        # Check that the geoip2 module can be imported
        # Doc: http://geoip2.readthedocs.io/en/latest/
        try:
            # GeoIP2 modules need to be imported as below
            import geoip2.database
            import geoip2.errors
        except ImportError:
            warning("Cannot import geoip2. Won't be able to plot the world.")
            return []
        # Check availability of database
        if not conf.geoip_city:
            warning("Cannot import the geolite2 CITY database.\n"
                    "Download it from http://dev.maxmind.com/geoip/geoip2/geolite2/"  # noqa: E501
                    " then set its path to conf.geoip_city")
            return []
        # Check availability of plotting devices
        try:
            import cartopy.crs as ccrs
        except ImportError:
            warning("Cannot import cartopy.\n"
                    "More infos on http://scitools.org.uk/cartopy/docs/latest/installing.html")  # noqa: E501
            return []
        if not MATPLOTLIB:
            warning("Matplotlib is not installed. Won't be able to plot the world.")  # noqa: E501
            return []

        # Open & read the GeoListIP2 database
        try:
            db = geoip2.database.Reader(conf.geoip_city)
        except Exception:
            warning("Cannot open geoip2 database at %s", conf.geoip_city)
            return []

        # Regroup results per trace
        ips = {}
        rt = {}
        ports_done = {}
        for s, r in self.res:
            ips[r.src] = None
            if s.haslayer(TCP) or s.haslayer(UDP):
                trace_id = (s.src, s.dst, s.proto, s.dport)
            elif s.haslayer(ICMP):
                trace_id = (s.src, s.dst, s.proto, s.type)
            else:
                trace_id = (s.src, s.dst, s.proto, 0)
            trace = rt.get(trace_id, {})
            if not r.haslayer(ICMP) or r.type != 11:
                if trace_id in ports_done:
                    continue
                ports_done[trace_id] = None
            trace[s.ttl] = r.src
            rt[trace_id] = trace

        # Get the addresses locations
        trt = {}
        for trace_id in rt:
            trace = rt[trace_id]
            loctrace = []
            for i in range(max(trace)):
                ip = trace.get(i, None)
                if ip is None:
                    continue
                # Fetch database
                try:
                    sresult = db.city(ip)
                except geoip2.errors.AddressNotFoundError:
                    continue
                loctrace.append((sresult.location.longitude, sresult.location.latitude))  # noqa: E501
            if loctrace:
                trt[trace_id] = loctrace

        # Load the map renderer
        plt.figure(num='Scapy')
        ax = plt.axes(projection=ccrs.PlateCarree())
        # Draw countries
        ax.coastlines()
        ax.stock_img()
        # Set normal size
        ax.set_global()
        # Add title
        plt.title("Scapy traceroute results")

        from matplotlib.collections import LineCollection
        from matplotlib import colors as mcolors
        colors_cycle = iter(mcolors.BASE_COLORS)
        lines = []

        # Split traceroute measurement
        for key, trc in six.iteritems(trt):
            # Get next color
            color = next(colors_cycle)
            # Gather mesurments data
            data_lines = [(trc[i], trc[i + 1]) for i in range(len(trc) - 1)]
            # Create line collection
            line_col = LineCollection(data_lines, linewidths=2,
                                      label=key[1],
                                      color=color)
            lines.append(line_col)
            ax.add_collection(line_col)
            # Create map points
            lines.extend([ax.plot(*x, marker='.', color=color) for x in trc])

        # Generate legend
        ax.legend()

        # Call show() if matplotlib is not inlined
        if not MATPLOTLIB_INLINED:
            plt.show()

        # Clean
        ax.remove()

        # Return the drawn lines
        return lines